pax_global_header00006660000000000000000000000064147107762200014520gustar00rootroot0000000000000052 comment=b300273d65f71d072ac632141e1a095fe340ea10 AntiMicroX-antimicrox-b300273/000077500000000000000000000000001471077622000161525ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/.clang-format000066400000000000000000000004511471077622000205250ustar00rootroot00000000000000BasedOnStyle: LLVM IndentWidth: 4 BreakBeforeBraces: Custom ColumnLimit: 125 IndentPPDirectives: BeforeHash BraceWrapping: AfterEnum: true AfterStruct: true AfterClass: true AfterControlStatement: true AfterFunction: true AfterUnion: true BreakConstructorInitializersBeforeComma: trueAntiMicroX-antimicrox-b300273/.github/000077500000000000000000000000001471077622000175125ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/.github/FUNDING.yml000066400000000000000000000015051471077622000213300ustar00rootroot00000000000000# These are supported funding model platforms github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry polar: AntiMicroX buy_me_a_coffee: # Replace with a single Buy Me a Coffee username custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] AntiMicroX-antimicrox-b300273/.github/ISSUE_TEMPLATE/000077500000000000000000000000001471077622000216755ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/.github/ISSUE_TEMPLATE/bug_report.yaml000066400000000000000000000034251471077622000247350ustar00rootroot00000000000000name: "\U0001F41E Bug Report" description: Create a bug report to help us fix it labels: ["bug"] body: - type: checkboxes attributes: label: Is there an existing issue for this? description: Please search to see if an issue already exists for the bug you encountered. options: - label: I searched the existing issues and did not find anything similar. required: true - type: textarea attributes: label: Current Behavior description: A concise description of what you're experiencing. validations: required: false - type: textarea attributes: label: Expected Behavior description: A concise description of what you expected to happen. validations: required: false - type: textarea attributes: label: Steps To Reproduce description: Steps to reproduce the behavior. placeholder: | 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error validations: required: false - type: textarea attributes: label: Environment description: | Copy and paste text from Info window (Help->About->Info) ❗Without this information issue will be instantly closed.❗ placeholder: | Program Version 3.3.2 Built Against SDL 2.24.0 Running With SDL 2.24.0 Using Qt 5.15.7 Using Event Handler: XTest Compositor type: x11 Host OS: Windows Version: 10 Architecture: x86_64 render: markdown validations: required: true - type: textarea attributes: label: Anything else? description: | Links? References? Anything that will give us more context about the issue you are encountering! Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. validations: required: falseAntiMicroX-antimicrox-b300273/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000002721471077622000236660ustar00rootroot00000000000000blank_issues_enabled: false contact_links: - name: "\U00002753 Question" url: https://github.com/AntiMicroX/antimicrox/discussions about: Please ask and answer questions here. AntiMicroX-antimicrox-b300273/.github/ISSUE_TEMPLATE/feature_request.yaml000066400000000000000000000033071471077622000257670ustar00rootroot00000000000000name: "\U0001F680 Feature Request" description: Suggest an idea for this project labels: ["enhancement"] body: - type: checkboxes attributes: label: Is there an existing issue for this? description: Please search to see if an issue already exists for the bug you encountered. options: - label: I have searched the existing issues required: true - type: textarea attributes: label: Is your feature request related to a problem? Please describe. description: A clear and concise description of what the problem is. placeholder: I'm always frustrated when I have to press this small button. validations: required: false - type: textarea attributes: label: Describe the solution you'd like description: A clear and concise description of what you want to happen. placeholder: Make this button bigger validations: required: false - type: textarea attributes: label: Describe alternatives you've considered description: A clear and concise description of any alternative solutions or features you've considered. placeholder: I wanted to but bigger display, but it would be too expensive. validations: required: false - type: textarea attributes: label: Additional context description: | Add any other context or screenshots about the feature request here. Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. validations: required: false - type: markdown attributes: value: | --- The more thumbs up 👍 your idea gets, the more likely it is that we'll implement it. ✨ AntiMicroX-antimicrox-b300273/.github/pull_request_template.md000066400000000000000000000011661471077622000244570ustar00rootroot00000000000000Closes #... ## Proposed changes - - - ---- AntiMicroX-antimicrox-b300273/.github/workflows/000077500000000000000000000000001471077622000215475ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/.github/workflows/code_formatting.yml000066400000000000000000000015441471077622000254420ustar00rootroot00000000000000name: Check code formatting concurrency: group: format-${{ github.head_ref }} cancel-in-progress: true on: push: branches: - master pull_request: branches: - master jobs: test: # The type of runner that the job will run on name: Check Code Formatting runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - name: Download tools run: | sudo apt-get update && sudo apt-get install clang-format-14 echo "Clang-format version" clang-format --version wget https://raw.githubusercontent.com/Sarcasm/run-clang-format/master/run-clang-format.py chmod +x ./run-clang-format.py - name: Test run: ./run-clang-format.py -r src AntiMicroX-antimicrox-b300273/.github/workflows/main.yml000066400000000000000000000155271471077622000232300ustar00rootroot00000000000000name: Build concurrency: group: build-${{ github.head_ref }} cancel-in-progress: true on: push: branches: - master pull_request: branches: - master workflow_dispatch: jobs: # Build job for Ubuntu build-ubuntu: strategy: fail-fast: false matrix: include: - name: Ubuntu 22-04 GCC QT5 image: ubuntu-22.04 cc: gcc cxx: g++ build-type: Debug experimental: false qt-packages: "qttools5-dev qttools5-dev-tools" - name: Ubuntu 22-04 GCC QT6 image: ubuntu-22.04 cc: gcc cxx: g++ build-type: Debug experimental: false qt-packages: "qt6-base-dev qt6-tools-dev qt6-tools-dev-tools libqt6core5compat6-dev qt6-l10n-tools linguist-qt6" - name: Ubuntu 22-04 Clang QT5 image: ubuntu-22.04 cc: clang cxx: clang++ build-type: Debug experimental: true qt-packages: "qttools5-dev qttools5-dev-tools" - name: Ubuntu 20-04 GCC (for AppImage comp) image: ubuntu-20.04 cc: gcc cxx: g++ build-type: Debug experimental: false qt-packages: "qttools5-dev qttools5-dev-tools" name: ${{ matrix.name }} ${{ matrix.build-type }} runs-on: ${{ matrix.image }} continue-on-error: ${{ matrix.experimental }} steps: - uses: actions/checkout@v3 - name: Install Dependencies run: sudo apt-get update && sudo apt-get install extra-cmake-modules libsdl2-dev libxi-dev libxtst-dev libx11-dev itstool gettext ninja-build ${{ matrix.qt-packages }} - name: Configure CMake run: cmake -GNinja -DCHECK_FOR_UPDATES=ON -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -B ${{ github.workspace }}/build env: CXX: ${{ matrix.cxx }} CC: ${{ matrix.cc }} - name: Build AntiMicroX run: cmake --build ${{ github.workspace }}/build # Build job for Windows build-windows: strategy: fail-fast: false matrix: include: - name: WinServer2019 MinGW QT5 image: windows-2019 qt-version: "5.15.2" shell: msys2 {0} build-type: Debug qt-arch: "win64_mingw81" experimental: false - name: WinServer2019 MinGW QT6 image: windows-2019 qt-version: "6.7" shell: msys2 {0} build-type: Debug qt-arch: "win64_mingw" experimental: false - name: WinServer2019 MSVC QT5 image: windows-2019 qt-version: "5.15.2" shell: cmd cmake-args: -G "Visual Studio 16 2019" "-DSDL2_PATH=%WORKSPACE_DIR%/sdl2/" "-DSDL2_LIBRARY=%WORKSPACE_DIR%/sdl2/lib/x64/SDL2.lib" "-DSDL2_INCLUDE_DIR=%WORKSPACE_DIR%/sdl2/" "-DSDL2_DLL_LOCATION_DIR=%WORKSPACE_DIR%/sdl2/lib/x64/SDL2.dll" build-type: Debug qt-arch: "win64_msvc2019_64" experimental: false - name: WinServer2019 MSVC QT6 image: windows-2019 qt-version: "6.7" shell: cmd cmake-args: -G "Visual Studio 16 2019" "-DSDL2_PATH=%WORKSPACE_DIR%/sdl2/" "-DSDL2_LIBRARY=%WORKSPACE_DIR%/sdl2/lib/x64/SDL2.lib" "-DSDL2_INCLUDE_DIR=%WORKSPACE_DIR%/sdl2/" "-DSDL2_DLL_LOCATION_DIR=%WORKSPACE_DIR%/sdl2/lib/x64/SDL2.dll" build-type: Debug qt-arch: "win64_msvc2019_64" experimental: false name: ${{ matrix.name }} ${{ matrix.build-type }} runs-on: ${{ matrix.image }} continue-on-error: ${{ matrix.experimental }} defaults: run: shell: ${{ matrix.shell }} steps: - uses: actions/checkout@v3 - name: Install Dependencies (msys2) if: startsWith(matrix.shell, 'msys2') uses: msys2/setup-msys2@v2 with: install: >- mingw-w64-x86_64-toolchain mingw-w64-x86_64-ninja msystem: mingw64 release: false #mingw-w64-x86_64-SDL2 not installed above because of: https://github.com/AntiMicroX/antimicrox/issues/465 - name: Install sdl2 (mingw-w64) if: startsWith(matrix.shell, 'msys2') run: | curl -L -o mingw-w64-x86_64-SDL2-2.30.6-1-any.pkg.tar.zst https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-SDL2-2.30.6-1-any.pkg.tar.zst pacman --noconfirm -U mingw-w64-x86_64-SDL2-2.30.6-1-any.pkg.tar.zst - name: Install sdl2 (msvc) if: startsWith(matrix.shell, 'cmd') run: | curl -L -o SDL2-devel-2.30.6-VC.zip https://github.com/libsdl-org/SDL/releases/download/release-2.30.6/SDL2-devel-2.30.6-VC.zip unzip SDL2-devel-2.30.6-VC.zip mv "${{ github.workspace }}/SDL2-2.30.6" "${{ github.workspace }}/sdl2" mklink /J "${{ github.workspace }}\sdl2\SDL2" "${{ github.workspace }}\sdl2\include" - name: Install MSVC if: startsWith(matrix.shell, 'cmd') uses: TheMrMilchmann/setup-msvc-dev@v2 with: arch: x64 toolset: 14.1 - name: Install Qt uses: jurplel/install-qt-action@v4 with: version: ${{ matrix.qt-version }} host: "windows" target: "desktop" arch: ${{ matrix.qt-arch }} dir: "${{ github.workspace }}/qt/" install-deps: "true" - name: Configure CMake run: cmake -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -B "${{ github.workspace }}/build" ${{ matrix.cmake-args }} env: CMAKE_PREFIX_PATH: "${{ env.QT_ROOT_DIR }}/lib/cmake" WORKSPACE_DIR: ${{ github.workspace }} - name: Build run: cmake --build "${{ github.workspace }}/build" --parallel 8 AntiMicroX-antimicrox-b300273/.github/workflows/release.yml000066400000000000000000000205211471077622000237120ustar00rootroot00000000000000name: Release on: release: types: [published] jobs: # Build .deb files for debian-based systems. build_deb: strategy: fail-fast: false matrix: include: - name: Ubuntu 22-04 image: ubuntu-22.04 - name: Ubuntu 20-04 image: ubuntu-20.04 name: Build deb package ${{ matrix.name }} runs-on: ${{ matrix.image }} steps: - uses: actions/checkout@v3 - name: Install Dependencies run: sudo apt-get update && sudo apt-get install extra-cmake-modules qttools5-dev qttools5-dev-tools libsdl2-dev libxi-dev libxtst-dev libx11-dev itstool gettext - name: Configure CMake run: cmake -DCPACK_GENERATOR="DEB" -DCMAKE_BUILD_TYPE=Release -DCHECK_FOR_UPDATES=ON -DANTIMICROX_PKG_VERSION="GitHub deb Release" -B ${{ github.workspace }}/build - name: Create Deb package id: create_deb run: cmake --build ${{ github.workspace }}/build --parallel 8 --target package - name: Rename deb files id: rename_debs run: | FILE=`find ${{ github.workspace }}/build/*.deb` NEWFILE=`echo $FILE | sed 's/x86_64/${{ matrix.image }}-x86_64/'` mv $FILE $NEWFILE # Upload generated files to release - name: Upload binaries to release uses: AButler/upload-release-assets@v2.0 with: files: ${{ github.workspace }}/build/*.deb repo-token: ${{ github.token }} # Build universal and portable AppImage package. build-appimage: # Version of ubuntu building this appimage, it shouldn't be the latest verion of ubuntu to avoid breaking compatibility with older systems name: Build AppImage package runs-on: ubuntu-20.04 steps: - name: Install Dependencies run: | sudo apt-get update sudo apt-get install extra-cmake-modules qttools5-dev qttools5-dev-tools libsdl2-dev libxi-dev libxtst-dev libx11-dev itstool gettext qt5-default zsync #Replace original library with the newer one - name: Build and install newer SDL2 run: | git clone https://github.com/libsdl-org/SDL.git -b release-2.30.6 cd SDL mkdir build cd build cmake .. cmake --build . sudo cmake --install . sudo cp /usr/local/lib/libSDL2-2.0.so.0 /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 - uses: actions/checkout@v3 - name: Prepare files needed to create AppImage run: | mkdir build && cd ./build wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage chmod +x linuxdeploy-x86_64.AppImage chmod +x appimagetool-x86_64.AppImage chmod +x linuxdeploy-plugin-qt-x86_64.AppImage - name: Build AntiMicroX run: | VERSION=`cat ./CMakeLists.txt | grep "set(ANTIMICROX_" | grep _VERSION | cut -d " " -f 2 | cut -d ")" -f 1` MAJOR=`echo $VERSION | cut -d " " -f 1` MINOR=`echo $VERSION | cut -d " " -f 2` PATCH=`echo $VERSION | cut -d " " -f 3` cd build cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DANTIMICROX_PKG_VERSION="$MAJOR.$MINOR.$PATCH-x86_64 GitHub AppImage Release" make install DESTDIR=AppDir -j8 # UPDATE_INFORMATION describes where information about updates can be found - name: Create AppImage file run: | cd build export UPDATE_INFORMATION="zsync|https://github.com/$GITHUB_REPOSITORY/releases/latest/download/antimicrox-x86_64.AppImage.zsync" ./linuxdeploy-x86_64.AppImage --appdir AppDir --plugin qt ./appimagetool-x86_64.AppImage AppDir/ -u "$UPDATE_INFORMATION" # Upload generated files to release - name: Upload binaries to release uses: AButler/upload-release-assets@v2.0 with: files: ./build/AntiMicroX*.AppImage;./build/AntiMicroX*.zsync repo-token: ${{ github.token }} - name: Build AntiMicroX-debug run: | VERSION=`cat ./CMakeLists.txt | grep "set(ANTIMICROX_" | grep _VERSION | cut -d " " -f 2 | cut -d ")" -f 1` MAJOR=`echo $VERSION | cut -d " " -f 1` MINOR=`echo $VERSION | cut -d " " -f 2` PATCH=`echo $VERSION | cut -d " " -f 3` cd build cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/usr -DANTIMICROX_PKG_VERSION="$MAJOR.$MINOR.$PATCH-debug-x86_64 \(AppImage-debug\)" make install DESTDIR=AppDir -j8 - name: Create AppImage debug file run: | cd build ./linuxdeploy-x86_64.AppImage --appdir AppDir --plugin qt ./appimagetool-x86_64.AppImage AppDir/ mv AntiMicroX-x86_64.AppImage AntiMicroX-debug-x86_64.AppImage # Upload generated files to release - name: Upload binaries to release uses: AButler/upload-release-assets@v2.0 with: files: ./build/AntiMicroX*.AppImage repo-token: ${{ github.token }} build-windows-packages: name: Create Windows packages runs-on: windows-2019 defaults: run: shell: msys2 {0} steps: - uses: actions/checkout@v3 - name: Install Dependencies uses: msys2/setup-msys2@v2 with: install: >- mingw-w64-x86_64-toolchain mingw-w64-x86_64-ninja mingw-w64-x86_64-nsis mingw-w64-x86_64-openssl msystem: mingw64 release: false # mingw-w64-x86_64-SDL2 not installed above because of: https://github.com/AntiMicroX/antimicrox/issues/465 # SDL2 version for release locked - name: Install sdl2 run: | curl -L -o mingw-w64-x86_64-SDL2-2.30.6-1-any.pkg.tar.zst https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-SDL2-2.30.6-1-any.pkg.tar.zst pacman --noconfirm -U mingw-w64-x86_64-SDL2-2.30.6-1-any.pkg.tar.zst - name: Install Qt uses: jurplel/install-qt-action@v4 with: version: "6.7" host: "windows" target: "desktop" arch: "win64_mingw" dir: "${{ github.workspace }}/qt/" install-deps: "true" - name: Configure CMake run: cmake -DCMAKE_BUILD_TYPE=Release -DCHECK_FOR_UPDATES=ON -DANTIMICROX_PKG_VERSION="GitHub Windows Release" -B '${{ github.workspace }}'/build env: CMAKE_PREFIX_PATH: "${{ env.QT_ROOT_DIR }}/lib/cmake" - name: Build Installer run: cmake --build '${{ github.workspace }}'/build --target package --parallel 8 - name: Configure CMake (portable) run: cmake -DCMAKE_BUILD_TYPE=Release -DCHECK_FOR_UPDATES=ON -DANTIMICROX_PKG_VERSION="GitHub Portable Windows Release" -DPORTABLE_WIN=ON -B '${{ github.workspace }}'/build env: CMAKE_PREFIX_PATH: "${{ env.QT_ROOT_DIR }}/lib/cmake" - name: Build ZIP Package run: cmake --build '${{ github.workspace }}'/build --target package --parallel 8 - name: Upload binaries to release uses: AButler/upload-release-assets@v2.0 with: files: build/antimicrox*.exe;build/antimicrox*.zip repo-token: ${{ github.token }} AntiMicroX-antimicrox-b300273/.github/workflows/static-code-analysis.yml000066400000000000000000000071061471077622000263160ustar00rootroot00000000000000name: Static Code Analysis concurrency: group: static-code-analysis-${{ github.head_ref }} cancel-in-progress: true on: push: branches: - master workflow_dispatch: jobs: # CodeQl Code Analysis helps discover security vulnerabilities in your code. # Official website: https://codeql.github.com/ # See the results here: https://github.com/AntiMicroX/antimicrox/security/code-scanning codeql-analysis: name: CodeQl Code Analysis runs-on: ubuntu-latest permissions: actions: read contents: read security-events: write steps: - name: Clone Repository uses: actions/checkout@v3 # Initialize CodeQl with language parameters - name: Initialize CodeQL uses: github/codeql-action/init@v2 with: languages: "cpp" # Project must be built before codeql can run its analysis - name: Install Dependencies run: sudo apt-get update && sudo apt-get install extra-cmake-modules qttools5-dev qttools5-dev-tools libsdl2-dev libxi-dev libxtst-dev libx11-dev itstool gettext ninja-build - name: Configure CMake run: cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -B ${{ github.workspace }}/build - name: Build AntiMicroX run: cmake --build ${{ github.workspace }}/build # Run codeql analysis - name: Run CodeQL uses: github/codeql-action/analyze@v3 infer-analysis: # Infer is a static analysis tool, it produces a list of potential bugs. # https://fbinfer.com/ # How to see the results? # 1. Goto Static Code Analysis GitHub Actions: https://github.com/AntiMicroX/antimicrox/actions/workflows/static-code-analysis.yml # 2. Click on the relevent workflow run (runs on push, pull_requestand manually using workflow_dispatch) # 3. Here you can see the artifact named "report", Download it to see the details. # 4. Or you can click on the "Infer Code Analysis" and check the "Run Infer" step. name: Infer Code Analysis runs-on: ubuntu-latest steps: - name: Clone Repository uses: actions/checkout@v3 # Download Infer and install at workflow run to ensure latest version - name: Install Dependencies run: | sudo apt-get update && sudo apt-get install extra-cmake-modules qttools5-dev qttools5-dev-tools libsdl2-dev libxi-dev libxtst-dev libx11-dev itstool gettext ninja-build curl -sSL "https://github.com/facebook/infer/releases/download/v1.1.0/infer-linux64-v1.1.0.tar.xz" | sudo tar -C /opt -xJ && sudo ln -s "/opt/infer-linux64-v1.1.0/bin/infer" /usr/local/bin/infer # Project must be built before infer can run its analysis, must export the compile_commands.json file - name: Configure CMake run: cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -B ${{ github.workspace }}/build - name: Build AntiMicroX run: cmake --build ${{ github.workspace }}/build # Run infer analysis using the compilation database - name: Run Infer run: infer run --compilation-database build/compile_commands.json # Upload result to build artifacts - name: Upload Results uses: actions/upload-artifact@v4 with: name: report path: infer-out/report.txt AntiMicroX-antimicrox-b300273/.github_changelog_generator000066400000000000000000000002061471077622000235100ustar00rootroot00000000000000user=AntiMicroX project=antimicrox since-tag=3.1.1 pr-label=**Notable merged pull requests:** issues-label=**Notable closed issues:** AntiMicroX-antimicrox-b300273/.gitignore000066400000000000000000000004551471077622000201460ustar00rootroot00000000000000# Build directories build/ builds/ build-dir/ Build/ .flatpak-builder/ repo/ docs/ # Changelogs src/Changelog src/CHANGELOG.md # IDE- related files .vscode/**/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json !.vscode/qt5.natvis.json !.vscode/snippets.md AntiMicroX-antimicrox-b300273/.vscode/000077500000000000000000000000001471077622000175135ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/.vscode/extensions.json000066400000000000000000000004071471077622000226060ustar00rootroot00000000000000{ "recommendations": [ "cschlosser.doxdocgen", "ms-vscode.cmake-tools", "ms-vscode.cpptools", "visualstudioexptteam.vscodeintellicode", "tonka3000.qtvsctools", "twxs.cmake", "xaver.clang-format", ] }AntiMicroX-antimicrox-b300273/.vscode/launch.json000077500000000000000000000033001471077622000216570ustar00rootroot00000000000000{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "cppdbg", "request": "launch", "name": "Open a core dump(c/c++)", "program": "${workspaceFolder}/build/bin/antimicrox", "coreDumpPath": "${input:coreFileName}", "cwd": "${workspaceFolder}", "MIMode": "gdb", "visualizerFile": "${workspaceFolder}/.vscode/qt5.natvis.xml" }, { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/bin/antimicrox", "args": [ "--log-level", "verbose" ], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Włącz formatowanie kodu dla gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "text": "-gdb-set follow-fork-mode child" } ], "visualizerFile": "${workspaceFolder}/.vscode/qt5.natvis.xml", "showDisplayString": true, } ], "inputs": [ { "id": "coreFileName", "type": "promptString", "description": "Enter core file path" } ] }AntiMicroX-antimicrox-b300273/.vscode/qt5.natvis.xml000066400000000000000000001006031471077622000222510ustar00rootroot00000000000000 {{ x = {xp}, y = {yp} }} xp yp {{ x = {x1}, y = {y1}, width = {x2 - x1 + 1}, height = {y2 - y1 + 1} }} x1 y1 x2 - x1 + 1 y2 - y1 + 1 {{ x = {xp}, y = {yp}, width = {w}, height = {h} }} xp yp w h {{ width = {wd}, height = {ht} }} wd ht {{ start point = {pt1}, end point = {pt2} }} {pt1} pt1 {pt2} pt2 {{ size = {d->size} }} d->ref.atomic._q_value d->size (QPoint*)((reinterpret_cast<char*>(d)) + d->offset) {{ size = {d->size} }} d->size > 0 && ((((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).xp == (((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).xp) && ((((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).yp == (((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).yp) d->ref.atomic._q_value d->size (QPointF*)((reinterpret_cast<char*>(d)) + d->offset) {{ x = {xp}, y = {yp} }} xp yp {{ x = {xp}, y = {yp}, z = {zp} }} xp yp zp {{ x = {xp}, y = {yp}, z = {zp}, w = {wp} }} xp yp zp wp {{ m11 = {_m11}, m12 = {_m12}, m21 = {_m21}, m22 = {_m22}, ... }} _m11 _m12 _m21 _m22 _dx _dy {{ m11 = {m[0][0]}, m12 = {m[1][0]}, m13 = {m[2][0]}, m14 = {m[3][0]}, ... }} m[0][0] m[1][0] m[2][0] m[3][0] m[0][1] m[1][1] m[2][1] m[3][1] m[0][2] m[1][2] m[2][2] m[3][2] m[0][3] m[1][3] m[2][3] m[3][3] {{ horizontal = {static_cast<Policy>(bits.horPolicy)}, vertical = {static_cast<Policy>(bits.verPolicy)}, type = {ControlType(1 << bits.ctype)} }} QSizePolicy::Policy::{static_cast<Policy>(bits.verPolicy)} QSizePolicy::Policy::{static_cast<Policy>(bits.horPolicy)} QSizePolicy::ControlType::{ControlType(1 << bits.ctype)} Qt::Vertical (2) Qt::Horizontal (1) static_cast<int>(bits.verStretch) static_cast<int>(bits.horStretch) bits.hfw == 1 bits.wfh == 1 {ucs,c} ucs,c ucs > 0xff ? '\0' : char(ucs),c ucs,c {((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub} ((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub d->size d->ref.atomic._q_value d->size ((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),c {((reinterpret_cast<char*>(d)) + d->offset),sb} ((reinterpret_cast<char*>(d)) + d->offset),sb d->size d->ref.atomic._q_value d->size ((reinterpret_cast<char*>(d)) + d->offset),c {{ size = {(d.d->size << 3) - *((reinterpret_cast<char*>(d.d)) + d.d->offset)} }} d.d->ref.atomic._q_value (d.d->size << 3) - *((reinterpret_cast<char*>(d.d)) + d.d->offset) (*(reinterpret_cast<const unsigned char*>((reinterpret_cast<char*>(d.d)) + d.d->offset) + 1 + ($i >> 3)) & (1 << ($i & 7))) != 0 {{ size = {s} }} a s ptr {{ julian day = {jd} }} {{ millisecond = {mds} }} {{ milliseconds = {mds} }} mds / 3600000, d mds / 3600000, d (mds % 3600000) / 60000, d (mds % 3600000) / 60000, d (mds / 1000) % 60, d (mds / 1000) % 60, d mds % 1000, d mds % 1000, d {d.pattern} ref._q_value strong reference to shared pointer of type {"$T1"} value == 0 d->weakref._q_value d->strongref._q_value pointer to implicit shared object of type {"$T1"} d pointer to explicit shared object of type {"$T1"} d guarded pointer to subclass of QObject of type {"$T1"} wp.d == 0 || wp.d->strongref._q_value == 0 || wp.value == 0 weak reference to shared pointer of type {"$T1"} d == 0 || d->strongref._q_value == 0 || value == 0 d->weakref._q_value d->strongref._q_value scoped pointer to a dynamically allocated object of type {"$T1"} !d scoped pointer to dynamically allocated array of objects of type {"$T1"} !d ({first}, {second}) first second {{ size = {d->size} }} d->ref.atomic._q_value d->size ($T1*)((reinterpret_cast<char*>(d)) + d->offset) {{ size = {d->end - d->begin} }} d->ref.atomic._q_value d->end - d->begin *reinterpret_cast<$T1*>((sizeof($T1) > sizeof(void*)) ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v : reinterpret_cast<$T1*>(d->array + d->begin + $i)) {{ size = {d->size} }} d->ref.atomic._q_value d->size d->n n (*(QLinkedListNode<$T1>*)this).t ({key}, {value}) key value {{ size = {d->size} }} d->ref.atomic._q_value d->size d->header.left left right *((QMapNode<$T1,$T2>*)this) (empty) ({key}, {value}) key value next {{ size = {d->size} }} d->numBuckets reinterpret_cast<Node **>(d->buckets) d->size node = *(bucket++) --n keyValuePair = reinterpret_cast<Node *>(node) keyValuePair->value node = node->next (empty) ({key}) key {{ size = {q_hash.d->size} }} q_hash ({*keyPtr}, {*t}) *keyPtr *t {{ size = {hash.d->size} }} mx total hash.d->ref.atomic._q_value hash.d->size f n *((Node*)this) Invalid {d.data.b} {d.data.i} {d.data.u} {d.data.ll} {d.data.ull} {d.data.d} {d.data.c} {*((QMap<QString,QVariant>*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QList<QVariant>*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QString*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QStringList*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QByteArray*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QBitArray*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QDate*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QTime*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} DateTime Url Locale {*((QRect*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QRectF*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QSize*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QSizeF*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QLine*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QLineF*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QPoint*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} {*((QPointF*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} RegExp RegularExpression {*((QHash<QString,QVariant>*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr)))} EasingCurve Uuid ModelIndex LastCoreType Font Pixmap Brush Color Palette Image Polygon Region Bitmap Cursor KeySequence Pen TextLength TextFormat Matrix Transform Matrix4x4 Vector2D Vector3D Vector4D Quaternion PolygonF Icon LastGuiType SizePolicy UserType LastType d.data.c *((QString*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QByteArray*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QMap<QString,QVariant>*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QList<QVariant>*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QString*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QStringList*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QByteArray*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QBitArray*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QDate*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QTime*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QRect*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QRectF*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QSize*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QSizeF*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QLine*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QLineF*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QPoint*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QPointF*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) *((QHash<QString,QVariant>*)(d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr))) AntiMicroX-antimicrox-b300273/.vscode/settings.json000077500000000000000000000014451471077622000222550ustar00rootroot00000000000000{ "files.associations": { "qtime": "cpp", "qhash": "cpp", "thread": "cpp", "new": "cpp", "bitset": "cpp", "atomic": "cpp", "qdesktopservices": "cpp", "qtranslator": "cpp", "qtextstream": "cpp", "qjsondocument": "cpp", "complex": "cpp", "cmath": "cpp" }, "[c]": { "editor.defaultFormatter": "xaver.clang-format", "editor.formatOnPaste": true, "editor.formatOnType": true, "editor.formatOnSave": true, }, "qttools.injectNatvisFile": false, "cmake.debugConfig": { "visualizerFile": "${workspaceFolder}/.vscode/qt5.natvis.xml", "showDisplayString": true, "args": [ "--log-level", "verbose" ], }, }AntiMicroX-antimicrox-b300273/.vscode/snippets.md000077500000000000000000000006531471077622000217110ustar00rootroot00000000000000# Useful snippets Check source of signal ```cpp QObject *obj = this->sender(); if (obj != nullptr) qInfo() << "objName ::" << obj->metaObject()->className() << endl << "method ::" << obj->metaObject()->method(senderSignalIndex()).methodSignature(); ``` To make antimicrox crash when warrning happens use command: `QT_FATAL_WARNINGS=1 ./build/bin/antimicrox` (Useful when used with debugger)AntiMicroX-antimicrox-b300273/BUILDING.md000066400000000000000000000226531471077622000177010ustar00rootroot00000000000000# Building AntiMicroX Most of these packages are already built and available on [Release Page](https://github.com/AntiMicroX/antimicrox/releases), but if you want, you can also build AntiMicroX by yourself. - [Building AntiMicroX](#building-antimicrox) - [Build Dependencies](#build-dependencies) - [Basic building](#basic-building) - [MSVC building tips](#msvc-building-tips) - [Build Options for CMake](#build-options-for-cmake) - [Universal Options](#universal-options) - [Linux Options](#linux-options) - [Building DEB package](#building-deb-package) - [Building RPM package](#building-rpm-package) - [Building AppImage](#building-appimage) - [Building Flatpak](#building-flatpak) - [Building Windows installer](#building-windows-installer) ## Build Dependencies This program is written in C++ using the [Qt](https://www.qt.io/) framework. A C++ compiler and a proper C++ build environment will need to be installed on your system prior to building this program. Under Debian and Debian-based distributions like Ubuntu, the easiest way to get a base build environment set up is to install the meta-package **build-essential**. The following packages are required to be installed on your system in order to build this program: - `g++` from `gcc` (or clang compiler) - `cmake` - `extra-cmake-modules` - QT libraries: - For QT6: `qt6-base-dev`, `qt6-tools-dev-tools` `libqt6core5compat6-dev` - For QT5: `qttools5-dev` and `qttools5-dev-tools` (`qt5-tools` on distros based on Arch Linux) - `libsdl2-dev` (`sdl2` on distros based on Arch Linux) (SDL2) - `libxi-dev` (`libxi` on distros based on Arch Linux) (Optional. Needed to compile with X11 and uinput support) - `libxtst-dev` (`libxtst` on distros based on Arch Linux) (Optional. Needed to compile with XTest support) - `libx11-dev` (`libx11` on distros based on Arch Linux) (Needed to compile with Qt5 support) - `itstool` (extracts messages from XML files and outputs PO template files, then merges translations from MO files to create translated XML files) - `gettext`
Fedora dependencies One-liner for installing above dependencies: ```bash sudo dnf install git make cmake gcc cmake extra-cmake-modules qt6-qttools-devel SDL2-devel libXi-devel libXtst-devel libX11-devel itstool gettext-devel; ```
Ubuntu/Debian dependencies One-liner for installing above dependencies: ```bash sudo apt install g++ cmake extra-cmake-modules qt6-base-dev qt6-tools-dev-tools libqt6core5compat6-dev libsdl2-dev libxi-dev libxtst-dev libx11-dev itstool gettext ninja-build ``` QT5 Variant: ```bash sudo apt install g++ cmake extra-cmake-modules qttools5-dev qttools5-dev-tools libsdl2-dev libxi-dev libxtst-dev libx11-dev itstool gettext ninja-build ```
Windows dependencies In case of Windows you need QT, SDL2 libraries, cmake and compiler (mingw for example). For setting up your environment you may use `msys2`. Alternatively, you may use `MSVC`.
## Basic building This way of building is useful for testing purposes. In order to build this program, open a terminal and cd into the antimicrox directory. Enter the following commands in order to: Clone repository ```bash git clone https://github.com/AntiMicroX/antimicrox.git ``` Build the program: ```bash cd antimicrox mkdir build && cd build cmake .. cmake --build . ``` Run built binaries ``` ./bin/antimicrox ``` #### MSVC building tips Recent versions of Visual Studio (2017+) have support for cmake projects. Under Visual Studio 2022, building AntiMicroX is quite straight forward. - Ensure you have compatable versions of [Qt](https://www.qt.io/download) (5.9 works as of writing,) and [SDL2-devel](https://github.com/libsdl-org/SDL/releases/) installed. - Open antimicrox as a local folder in VS22. It should pick up the `CMakeLists.txt` and offer an option to open the CMake settings editor. If it doesn't, right click on `CMakeLists.txt` in the solution explorer and select `CMake settings for antimicrox`. - In the `Command arguments` section, add an argument to tell CMake where to find your Qt; E.g.: `"-DCMAKE_PREFIX_PATH=C:\Qt\5.9\msvc2017_64\lib\cmake"`. As of writing, Qt's msvc2017 works properly through vs22. - Under the `Cmake variables and cache` section, click the link labeled `Save and generate cmake cache to load variables. - If the CMake generation fails due to SDL2, find the variables named `SDL2_PATH`, `SDL2_INCLUDE_DIR`, and `SDL2_DLL_LOCATION_DIR` in the list view, and set them properly. You may also need to move the headers in the SDL2 include dir inside a folder named `SDL2` to match their include paths on other systems. - At this point you should be able to save your changes to regenerate the cmake cache, which will then allow you to build `antimicrox.exe` through Visual Studio. A recommended way of installation is building package typical for for your system (or building universal one like an AppImage).
Installation using cmake (not recommended) This way of installation is not recommended, because it doesn't integrate very well with some environments. Install: ```bash sudo cmake --install . ``` Uninstall: ```bash sudo make uninstall ```
### Build Options for CMake There are a few application specific options that can be used when running cmake to build antimicrox. The following file will attempt to list some of those options and describe their use in the project. ### Universal Options -DBUILD_DOCS Default: OFF. Build documentation using doxygen (installed doxygen and dot required). Generated files can be found in `docs` directory -DUPDATE_TRANSLATIONS Default: OFF. Set updateqm target to call lupdate in order to update translation files from source. -DCMAKE_BUILD_TYPE Default: Not defined. You can define build type. Debug builds are compiled with enabled debug flags, disabled optimizations and better printing stack trace in case of crash. -DTRANS_REMOVE_OBSOLETE Default: OFF. Do not specify -noobsolete option when calling lupdate command for qm files. -noobsolete is a method for getting rid of obsolete text entries -DCHECK_FOR_UPDATES Default: OFF. Show update button in GUI when newer version is available. Recommended for builds distributed without package management systems. -DWITH_TESTS Default: OFF. Allows for the launch of test sources with unit tests -DANTIMICROX_PKG_VERSION Default: Not defined. (feature intended for packagers) Manually define version of package displayed in info tab. When not defined building time is displayed instead. Example: `-DANTIMICROX_PKG_VERSION=3.1.7-appimage` ### Linux Options -DAPPDATA Default: ON. Build the project with AppData support. -DWITH_UINPUT Default: ON. Compile the program with uinput support. -DINSTALL_UINPUT_UDEV_RULES Default: ON. During installation process create new udev rule allowing regular users using uinput. -DWITH_X11 Default: ON. Compile the program with X11 support. -DWITH_XTEST Default: ON. Compile the program with XTest support. --- **qDebug output on terminal:** On some systems, particularly if you do not have QtCreator installed, you may notice that some debug info (in particular qDebug() statements) do not generate any output on a Linux terminal. To fix this, you can create a qtlogging.ini file: mkdir ~/.config/QtProject printf '[Rules]\n*.debug=true\nqt.*.debug=false\n' > ~/.config/QtProject/qtlogging.ini Once this file is created and has the debug rules present, it should be picked up and applied automatically the next time you run cmake to create a build. ## Building DEB package ```bash cd antimicrox mkdir build && cd build cmake .. -DCPACK_GENERATOR="DEB" cmake --build . --target package ``` ## Building RPM package If your distribution doesn't yet have an RPM package, you can easily build one for yourself. ```bash cd antimicrox mkdir build && cd build cmake .. -DCPACK_GENERATOR="RPM" cmake --build . --target package ``` ## Building AppImage Create build directory ```bash mkdir build && cd ./build ``` Download tools used for creating appimages (and make them executable) ```bash wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage chmod +x linuxdeploy-x86_64.AppImage chmod +x appimagetool-x86_64.AppImage chmod +x linuxdeploy-plugin-qt-x86_64.AppImage ``` Build antimicrox and install it in AppDir directory ```bash cmake .. -DCMAKE_INSTALL_PREFIX=/usr make make install DESTDIR=AppDir ``` Create AppImage file ```bash ./linuxdeploy-x86_64.AppImage --appdir AppDir --plugin qt ./appimagetool-x86_64.AppImage AppDir/ ``` ## Building Flatpak The command builds the package into the `build` folder and installs the created flatpak. The Flathub manifest can be located in [Flathub's Github repo](https://github.com/flathub/io.github.antimicrox.antimicrox). ```bash flatpak install flathub org.kde.Platform//5.11 org.kde.Sdk//5.11 flatpak-builder --user --install build/ other/io.github.antimicrox.antimicrox.yml --force-clean ``` ## Building Windows installer In case of building Windows package you will need [NSIS](https://nsis.sourceforge.io/Download). ``` cmake -DCMAKE_BUILD_TYPE=Debug -B .\build cmake --build .\build --target package ``` AntiMicroX-antimicrox-b300273/CHANGELOG.md000066400000000000000000002114061471077622000177670ustar00rootroot00000000000000# Changelog ## [3.5.0](https://github.com/AntiMicroX/antimicrox/tree/3.5.0-rc) (2024-10-31) **Fixed bugs:** - Horizontal mouse wheel is too fast when set on stick [\#1024](https://github.com/AntiMicroX/antimicrox/issues/1024) (by [sk2449](https://github.com/sk2449)) - Fix binding labels for Wheel Left/Right buttons [pull 1038](https://github.com/AntiMicroX/antimicrox/pull/1038) (by [sk2449](https://github.com/sk2449)) - Set change sometimes returns to wrong set [\#1050](https://github.com/AntiMicroX/antimicrox/issues/1050) - Wrong Keyboard Input on Assignment (Wayland) [\#300](https://github.com/AntiMicroX/antimicrox/issues/300) **Notable changes:** - Update translation for Finnish, Dutch, Russian - New translation: Indonesian - Fixed Builds for QT6 on Windows - Switched to QT6 on Windows Release Build ## [3.4.1](https://github.com/AntiMicroX/antimicrox/tree/3.4.1) (2024-08-10) **Fixed bugs:** - Fix issues with accelerometer stability [pull 1011](https://github.com/AntiMicroX/antimicrox/pull/1011) (by [pepper-jelly](https://github.com/pepper-jelly)) - Issue with float value for "Auto Reset Cycle After" [\#1002](https://github.com/AntiMicroX/antimicrox/issues/1002) (by [pepper-jelly](https://github.com/pepper-jelly)) - Accelerometer triggers when switching sets [\#991](https://github.com/AntiMicroX/antimicrox/issues/991) (by [pepper-jelly](https://github.com/pepper-jelly)) **Notable changes:** - Link AntimicroX repository with issue hunting platform: [Polar.sh](https://polar.sh/) - Bump SDL version to 2.30.6 - Refactor outdated pieces of code [pull 948](https://github.com/AntiMicroX/antimicrox/pull/948) [pull 950](https://github.com/AntiMicroX/antimicrox/pull/950) - Update more universal QT libraries detection [pull 957](https://github.com/AntiMicroX/antimicrox/pull/957) - Allow easy building with QT6 and ensure compatability [pull 919](https://github.com/AntiMicroX/antimicrox/pull/919), [pull 972](https://github.com/AntiMicroX/antimicrox/pull/972) - Drop Windows XP support [pull 980](https://github.com/AntiMicroX/antimicrox/pull/980) - Bump minimal QT version requirement to 5.10 [\#996](https://github.com/AntiMicroX/antimicrox/issues/996) **Implemented enhancements:** - Updated translations: Chinese, Portugese, German, French and Finnish - Added Catalan language And a lot of minor fixes and cleanups linked with QT6 and not only. ## [3.4.0](https://github.com/AntiMicroX/antimicrox/tree/3.4.0) (2024-03-10) **Fixed bugs:** - Fix attaching window to a pinned launcher in Linux [pull 886](https://github.com/AntiMicroX/antimicrox/pull/886) (by [mmmaisel](https://github.com/mmmaisel)) - Fixing builds with X11=OFF [pull 927](https://github.com/AntiMicroX/antimicrox/pull/927) (by [sjoblomj](https://github.com/sjoblomj)) **Notable changes:** - Bump SDL version to 2.30.1 - Updated translations - New translations: Croatian, Turkish, Persian, Vietnamese - Fix a lot of deprecation warnings and other code changes required to migrate to QT6 [\#446](https://github.com/AntiMicroX/antimicrox/issues/446) ## [3.3.4](https://github.com/AntiMicroX/antimicrox/tree/3.3.4) (2023-06-03) **Implemented enhancements:** - Update translations: Portugese(Brazil), Russian, Norwegian Bokmal - Add translations: Swedish **Fixed bugs:** - Fix and refactor adding default autoprofile [\#727](https://github.com/AntiMicroX/antimicrox/issues/727) - Fix GUI does not recognize super + action [\#749](https://github.com/AntiMicroX/antimicrox/issues/749) - Fix /dev/uinput static device node access [pull 781](https://github.com/AntiMicroX/antimicrox/pull/781) (by [lnussel](https://github.com/lnussel)) - Fix building for SDL version between 2.0.12 and 2.0.16 [\#788](https://github.com/AntiMicroX/antimicrox/issues/788) **Notable changes:** - Build AppImage package on Ubuntu 20.04 - Bump SDL version for AppImage and Windows from 2.0.20 to 2.26.5 ## [3.3.3](https://github.com/AntiMicroX/antimicrox/tree/3.3.3) (2023-01-30) **Implemented enhancements:** - Add checkbox enabling numeric keypad in ButtonEditDialog [\#168](https://github.com/AntiMicroX/antimicrox/issues/168) - Add MSVC cmake support. [\#667](https://github.com/AntiMicroX/antimicrox/pull/667) (by [nitz](https://github.com/nitz)) - Update translations: Spanish, Korean, Russian - Add translations: Rusyn, Portugese(Brazil) **Fixed bugs:** - Name mismatch in set selector list [\#655](https://github.com/AntiMicroX/antimicrox/issues/655) - Fix broken loading recently used profile for Windows 11 [\#632](https://github.com/AntiMicroX/antimicrox/issues/632) (by [nitz](https://github.com/nitz)) - Shebang ignored in execute bind [\#699](https://github.com/AntiMicroX/antimicrox/issues/699) - Mouse spring mode not working in wayland session [\#521](https://github.com/AntiMicroX/antimicrox/issues/521) **Notable changes:** - Some code refactors and docs updates - Logs improvements ## [3.3.2](https://github.com/AntiMicroX/antimicrox/tree/3.3.2) (2022-11-21) **Implemented enhancements:** - Use proper theme-based color for tab text [\#583](https://github.com/AntiMicroX/antimicrox/pull/583) - Show joystick battery level in tab [\#596](https://github.com/AntiMicroX/antimicrox/pull/596) **Fixed bugs:** - Fix broken obtaining path of active window by auto profile [\#592](https://github.com/AntiMicroX/antimicrox/pull/592) - Fix auto profile dialog does not populate title and application fields - Fix misspeled __BIG_ENDIAN constant [\#609](https://github.com/AntiMicroX/antimicrox/pull/599) - Fix advanced settings dialog freezes when pressing join on Linux [\#609](https://github.com/AntiMicroX/antimicrox/pull/609) - Remove disabling Auto-profile title box [\#619](https://github.com/AntiMicroX/antimicrox/pull/619) **Notable changes:** - don't minimize to taskbar by default on Linux [\#611](https://github.com/AntiMicroX/antimicrox/pull/611) **Full Changelog**: https://github.com/AntiMicroX/antimicrox/compare/3.3.1...3.3.2 ## [3.3.1](https://github.com/AntiMicroX/antimicrox/tree/3.3.1) (2022-10-24) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.3.0...3.3.1) Hotfix release reverting PR [\#555](https://github.com/AntiMicroX/antimicrox/pull/555) which can cause segfaults. ## [3.3.0](https://github.com/AntiMicroX/antimicrox/tree/3.3.0) (2022-10-24) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.2.5...3.3.0) **Implemented enhancements:** - Add support for DualSense trigger haptic feedback [\#503](https://github.com/AntiMicroX/antimicrox/pull/503) (by [mmmaisel](https://github.com/mmmaisel)) - Add Portable Windows build [\#523](https://github.com/AntiMicroX/antimicrox/pull/523) (by [AntumDeluge](https://github.com/AntumDeluge)) **Fixed bugs:** - Broken auto profile saving for Windows [\#492](https://github.com/AntiMicroX/antimicrox/pull/492) - Selection "None" Preset does not change button labels [\#513](https://github.com/AntiMicroX/antimicrox/pull/513) - Broken spring mouse Event on Windows [\#518](https://github.com/AntiMicroX/antimicrox/pull/518) - Multiple problems caused by invalid thread handling [\#573](https://github.com/AntiMicroX/antimicrox/pull/573) - Saving PS4 Controller setup stops set toggle from working - Saving Breaks Set Switching - Saving config breaks turbo - Warnings `QObject: Cannot create children for a parent that is in a different thread` **Notable changes:** - Fix some code warnings [\#497](https://github.com/AntiMicroX/antimicrox/pull/497) [\#558](https://github.com/AntiMicroX/antimicrox/pull/558) [\#559](https://github.com/AntiMicroX/antimicrox/pull/559) (by [pktiuk](https://github.com/pktiuk) and [Stefan-TU](https://github.com/Stefan-TU)) - Remove some unused code [\#504](https://github.com/AntiMicroX/antimicrox/pull/504) (by [mmmaisel](https://github.com/mmmaisel)) - Limit number of logged events - Include Visual Studio Code config files - Some refactors and docs updates - Update SDL mappings database - Update translations: Korean, Ukrainian, Spanish ## [3.2.5](https://github.com/AntiMicroX/antimicrox/tree/3.2.5) (2022-07-18) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.2.4...3.2.5) Test release containing changes implementing motion sensor support. **Implemented enhancements:** - Implement motion sensor support. [\#416](https://github.com/AntiMicroX/antimicrox/pull/416) (by [mmmaisel](https://github.com/mmmaisel)) - Allow storing calibration for multiple controllers in a profile [\#460](https://github.com/AntiMicroX/antimicrox/pull/460) (by [mmmaisel](https://github.com/mmmaisel)) **Fixed bugs:** - Crash on close after copying set. [\#454](https://github.com/AntiMicroX/antimicrox/issues/454) (by [mmmaisel](https://github.com/mmmaisel)) **Notable changes:** - Remove unused "Game Controller Mapping" button. ## [3.2.4](https://github.com/AntiMicroX/antimicrox/tree/3.2.4) (2022-06-11) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.2.3...3.2.4) **Implemented enhancements:** - Implement modifier button threshold zone [\#310](https://github.com/AntiMicroX/antimicrox/issues/310) (by [mmmaisel](https://github.com/mmmaisel)) - This allows mapping the analog range of a stick to walk/run in game without dedicated spring button. **Fixed bugs:** - Fix mouse calculations for multiple mice [\#435](https://github.com/AntiMicroX/antimicrox/pull/435) (by [mmmaisel](https://github.com/mmmaisel)) - Fix flickering JoyControlStickEditDialog layout [\#440](https://github.com/AntiMicroX/antimicrox/pull/440) (by [mmmaisel](https://github.com/mmmaisel)) - Implement proper offset and gain stick calibration [\#441](https://github.com/AntiMicroX/antimicrox/pull/441) (by [mmmaisel](https://github.com/mmmaisel)) **Notable changes:** - Increase minimum size of ButtonEditDialog [\#439](https://github.com/AntiMicroX/antimicrox/pull/439) (by [mmmaisel](https://github.com/mmmaisel)) - Fixes in translation utulities - Rename flag TRANS_KEEP_OBSOLETE to TRANS_REMOVE_OBSOLETE to improve readability - Fix wrong argument for utility deleting obsolete translations [\#445](https://github.com/AntiMicroX/antimicrox/pull/445) - Update translations: - Russian - Finnish - French - Chinese - Portuguese ## [3.2.3](https://github.com/AntiMicroX/antimicrox/tree/3.2.3) (2022-03-24) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.2.2...3.2.3) **Fixed bugs:** - Fixed bug: auto profile not saved when exe path is not defined [\#252](https://github.com/AntiMicroX/antimicrox/issues/252) **Notable changes:** - Added missing license for SDL_GameControllerDB - Many updates in translations: - Added Finnish translation by [heidiwenger](https://github.com/heidiwenger) - Added Norwegian Bokmål translation bu [comradekingu](https://github.com/comradekingu) - Updated German, French, Italian and Polish translations - update translation files - Always show battery level in joystick status window (even when unknown) - Multiple refactors and cleanups removing deprecated code (kudos to [mmmaisel](https://github.com/mmmaisel)). ## [3.2.2](https://github.com/AntiMicroX/antimicrox/tree/3.2.2) (2022-02-24) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.2.1...3.2.2) **Implemented enhancements:** - Add support for special characters in Windows log files [\#363](https://github.com/AntiMicroX/antimicrox/pull/363) - Change default working directory of launched executables [\#377](https://github.com/AntiMicroX/antimicrox/pull/377) **Fixed bugs:** - Fix typo (setting->settings) (by [jose1711](https://github.com/jose1711)) - Random Crashes during longer sessions [\#133](https://github.com/AntiMicroX/antimicrox/issues/133) - File with gamecontroller mappings not found [\#364](https://github.com/AntiMicroX/antimicrox/pull/364) - Empty application path in autoprofile [/#371](https://github.com/AntiMicroX/antimicrox/pull/371) **Notable changes:** - Enable checking for updates in Debian builds from GitHub - Log improvements and cleanup [\#336](https://github.com/AntiMicroX/antimicrox/pull/336) [\#342](https://github.com/AntiMicroX/antimicrox/pull/342) - Daemon mode support removed [\#345](https://github.com/AntiMicroX/antimicrox/pull/345) - Remove unused "map" and "display" argument options [\#350](https://github.com/AntiMicroX/antimicrox/pull/350) - Remove unused files With icons, resources and pertially implemented importing utility - Use colourful antimicrox icon in tray by default [\#361](https://github.com/AntiMicroX/antimicrox/pull/361) - Update building docs [\#370](https://github.com/AntiMicroX/antimicrox/pull/370) (by [zpangwin](https://github.com/zpangwin)) ## [3.2.1](https://github.com/AntiMicroX/antimicrox/tree/3.2.1) (2022-01-03) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.2.0...3.2.1) **Implemented enhancements:** - Add note about available update (enabled in Windows) [\#325](https://github.com/AntiMicroX/antimicrox/issues/325) - Add database of SDL gamepad mappings (more gamepads will be enabled by default) [\#296](https://github.com/AntiMicroX/antimicrox/issues/296) - Add proper printing information about connected devices to logs [\#282](https://github.com/AntiMicroX/antimicrox/issues/282) - Apply proper theme to Windows version of app [\#279](https://github.com/AntiMicroX/antimicrox/issues/279) - Add handling SIGABRT \(with printing stack\) [\#281](https://github.com/AntiMicroX/antimicrox/pull/281) - Set theme for Windows [\#317](https://github.com/AntiMicroX/antimicrox/pull/317) - Update QT version used in Windows Release to 5.15 [\#326](https://github.com/AntiMicroX/antimicrox/pull/326) **Fixed bugs:** - Crashes linked with deleting child objects [\#320](https://github.com/AntiMicroX/antimicrox/issues/320) - Broken Auto Profile list on Windows [\#278](https://github.com/AntiMicroX/antimicrox/issues/278) - Auto Profile Wrongly Shows Languages [\#273](https://github.com/AntiMicroX/antimicrox/issues/273) - Missing .dll files after Windows installation [\#268](https://github.com/AntiMicroX/antimicrox/issues/268) - Missing autoprofile settings tab in Windows [\#277](https://github.com/AntiMicroX/antimicrox/pull/277) **Notable changes:** - Add note about lack of AutoProfiles for Wayland users [\#314](https://github.com/AntiMicroX/antimicrox/issues/314) - Add message informaing about solutions in case of problems with uinput [\#248](https://github.com/AntiMicroX/antimicrox/pull/248) - Log improvements [\#322](https://github.com/AntiMicroX/antimicrox/pull/322) [\#336](https://github.com/AntiMicroX/antimicrox/pull/336) - Disable calibration for devices without joysticks [\#283](https://github.com/AntiMicroX/antimicrox/pull/283) - Clarification of names and --profile flag description [\#305](https://github.com/AntiMicroX/antimicrox/pull/305) **Others:** - Update copyright date [\#334](https://github.com/AntiMicroX/antimicrox/pull/334) - Cleanup daemon launching [\#331](https://github.com/AntiMicroX/antimicrox/pull/331) - Make Changelog links clickable [\#327](https://github.com/AntiMicroX/antimicrox/pull/327) - Print descriptions of devices in logs [\#319](https://github.com/AntiMicroX/antimicrox/pull/319) - Add experimental support for clang [\#288](https://github.com/AntiMicroX/antimicrox/pull/288) ([avinal](https://github.com/avinal)) - CI: Add concurrency and remove redundant lines [\#272](https://github.com/AntiMicroX/antimicrox/pull/272) ([avinal](https://github.com/avinal)) - CI: Add CodeQL and infer static code analysis [\#289](https://github.com/AntiMicroX/antimicrox/issues/289) [\#287](https://github.com/AntiMicroX/antimicrox/issues/287) ## [3.2.0](https://github.com/AntiMicroX/antimicrox/tree/3.2.0) (2021-10-29) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.1.7...3.2.0) First AntiMicroX release supporting Windows **Implemented enhancements:** - Prepare installer for Windows [\#237](https://github.com/AntiMicroX/antimicrox/issues/237) - Handle segfaults and other crashes in code [\#235](https://github.com/AntiMicroX/antimicrox/issues/235) - Create config for debug builds [\#218](https://github.com/AntiMicroX/antimicrox/issues/218) - Allow unhiding app window when second instance of AntiMicroX is launched [\#257](https://github.com/AntiMicroX/antimicrox/pull/257) **Fixed bugs:** - Typo in udev rule name: 60-antimicrox-uinput.rules instead 60-antimcrox-uinput.rules? [\#204](https://github.com/AntiMicroX/antimicrox/issues/204) **Notable merged pull requests:** - Move gui-related files to separate directory [\#253](https://github.com/AntiMicroX/antimicrox/pull/253) ([pktiuk](https://github.com/pktiuk)) - Logging system improvements [\#250](https://github.com/AntiMicroX/antimicrox/pull/250) ([pktiuk](https://github.com/pktiuk)) - Some additional logs and notes [\#233](https://github.com/AntiMicroX/antimicrox/pull/233) [\#249](https://github.com/AntiMicroX/antimicrox/pull/249) ([pktiuk](https://github.com/pktiuk)) - Fix compile warnings [\#246](https://github.com/AntiMicroX/antimicrox/pull/246) [\#242](https://github.com/AntiMicroX/antimicrox/pull/242) ([pktiuk](https://github.com/pktiuk)) - Set homepage url for packages [\#245](https://github.com/AntiMicroX/antimicrox/pull/245) ([pktiuk](https://github.com/pktiuk)) - Create config for debug build [\#243](https://github.com/AntiMicroX/antimicrox/pull/243) ([pktiuk](https://github.com/pktiuk)) - Cmake cleanup [\#219](https://github.com/AntiMicroX/antimicrox/pull/219) ([pktiuk](https://github.com/pktiuk)) **Pull requests restoring Windows support:** - Add Cpack NSIS config for building packages [\#262](https://github.com/AntiMicroX/antimicrox/pull/262) ([pktiuk](https://github.com/pktiuk)) - Restore full functionality of Windows build [\#225](https://github.com/AntiMicroX/antimicrox/pull/225) ([pktiuk](https://github.com/pktiuk)) - Restore Windows build [\#220](https://github.com/AntiMicroX/antimicrox/pull/220) [\#244](https://github.com/AntiMicroX/antimicrox/pull/244) ([pktiuk](https://github.com/pktiuk)) - Embed icon into windows executable [\#261](https://github.com/AntiMicroX/antimicrox/pull/261) ([pktiuk](https://github.com/pktiuk)) - Saves migration win [\#266](https://github.com/AntiMicroX/antimicrox/pull/266) ([pktiuk](https://github.com/pktiuk)) - Use -rdynamic only in Unix debug builds [\#259](https://github.com/AntiMicroX/antimicrox/pull/259) ([pktiuk](https://github.com/pktiuk)) - Setup Github Actions for Windows build [\#260](https://github.com/AntiMicroX/antimicrox/pull/260) ([avinal](https://github.com/avinal)) ## [3.1.7](https://github.com/AntiMicroX/antimicrox/tree/3.1.7) (2021-09-10) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.1.6...3.1.7) **Implemented enhancements:** - Wayland support for keyboard emulation [\#32](https://github.com/AntiMicroX/antimicrox/issues/32) **Fixed bugs:** - Load save dialogue window won't show saved configs = can't open saves [\#123](https://github.com/AntiMicroX/antimicrox/issues/123) - Segmentation Fault when change profile from command line [\#76](https://github.com/AntiMicroX/antimicrox/issues/76) **Notable merged pull requests:** - Include Appstream information into AppImage Build [\#201](https://github.com/AntiMicroX/antimicrox/pull/201) ([pktiuk](https://github.com/pktiuk)) - fix: Remove warning "QLocalSocket::waitForDisconnected\(\) is not allow… [\#200](https://github.com/AntiMicroX/antimicrox/pull/200) ([pktiuk](https://github.com/pktiuk)) - Crash-related fixes linked with memory management [\#194](https://github.com/AntiMicroX/antimicrox/pull/194) [\#196](https://github.com/AntiMicroX/antimicrox/pull/196) [\#198](https://github.com/AntiMicroX/antimicrox/pull/198) ([pktiuk](https://github.com/pktiuk)) - refactor: Improve log showing gamepad name [\#195](https://github.com/AntiMicroX/antimicrox/pull/195) ([pktiuk](https://github.com/pktiuk)) - refactor: Refactor executing commands [\#192](https://github.com/AntiMicroX/antimicrox/pull/192) ([pktiuk](https://github.com/pktiuk)) - Allow regular users using uinput [\#188](https://github.com/AntiMicroX/antimicrox/pull/188) ([pktiuk](https://github.com/pktiuk)) - feat: switch from xtest to uinput when wayland is detected [\#186](https://github.com/AntiMicroX/antimicrox/pull/186) ([pktiuk](https://github.com/pktiuk)) ## [3.1.6](https://github.com/AntiMicroX/antimicrox/tree/3.1.6) (2021-08-14) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.1.5...3.1.6) **Fixed bugs:** - Saving logs into file doesn't work properly. [\#78](https://github.com/AntiMicroX/antimicrox/issues/78) - Doesn't save my configurations/Wont auto load [\#70](https://github.com/AntiMicroX/antimicrox/issues/70) **Notable closed issues:** - Refactor logging system [\#177](https://github.com/AntiMicroX/antimicrox/issues/177) **Other merged pull requests:** - Add new logs associated with loading profile files [\#182](https://github.com/AntiMicroX/antimicrox/pull/182) ([pktiuk](https://github.com/pktiuk)) - Refactor arguments parsing [\#174](https://github.com/AntiMicroX/antimicrox/pull/174) ([pktiuk](https://github.com/pktiuk)) - docs: Add information about commandline for flatpak packages [\#173](https://github.com/AntiMicroX/antimicrox/pull/173) ([pktiuk](https://github.com/pktiuk)) - Added openSUSE instruction [\#158](https://github.com/AntiMicroX/antimicrox/pull/158) ([Mailaender](https://github.com/Mailaender)) ## [3.1.5](https://github.com/AntiMicroX/antimicrox/tree/3.1.5) (2021-03-14) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.1.4...3.1.5) Big thanks to @mirabilos for help with Debian packages migration and cleaning up project. **Notable closed issues:** - Migrate DEB packages to antimicrox [\#87](https://github.com/AntiMicroX/antimicrox/issues/87) - Integrate builds marking with docs cmake and CI [\#143](https://github.com/AntiMicroX/antimicrox/pull/143) **Other merged pull requests:** - Allow cleaner marking package builds [\#143](https://github.com/AntiMicroX/antimicrox/pull/143) ([mirabilos](https://github.com/mirabilos)) - fix appdata formatting [\#142](https://github.com/AntiMicroX/antimicrox/pull/142) ([mirabilos](https://github.com/mirabilos)) - apply lintian-provided spelling fixes [\#141](https://github.com/AntiMicroX/antimicrox/pull/141) ([mirabilos](https://github.com/mirabilos)) - fix the manpage \(hyphen as minus sign\) [\#140](https://github.com/AntiMicroX/antimicrox/pull/140) ([mirabilos](https://github.com/mirabilos)) - fix: change deb arch prefix for building AppImage [\#135](https://github.com/AntiMicroX/antimicrox/pull/135) ([pktiuk](https://github.com/pktiuk)) ## [3.1.4](https://github.com/AntiMicroX/antimicrox/tree/3.1.4) (2021-01-11) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.1.3...3.1.4) Kudos to @Janfel for PR! **Implemented enhancements:** - Remove qglobalshortcuts [\#106](https://github.com/AntiMicroX/antimicrox/issues/106) - File cleanup [\#104](https://github.com/AntiMicroX/antimicrox/issues/104) - Cmakefile fixes [\#102](https://github.com/AntiMicroX/antimicrox/issues/102) - Add dark tray icon [\#66](https://github.com/AntiMicroX/antimicrox/issues/66) - Icons overhaul [\#61](https://github.com/AntiMicroX/antimicrox/issues/61) - Automate generating changelogs [\#10](https://github.com/AntiMicroX/antimicrox/issues/10) **Fixed bugs:** - Clear shortcut not working [\#116](https://github.com/AntiMicroX/antimicrox/issues/116) - Assigning Text Entry to button doesn't assign proper string. [\#79](https://github.com/AntiMicroX/antimicrox/issues/79) - The uninstallation leaves several folders and files behind \(cmake\) [\#68](https://github.com/AntiMicroX/antimicrox/issues/68) **Notable closed issues:** - Remove antilib shared object because it's not really shared! [\#98](https://github.com/AntiMicroX/antimicrox/issues/98) **Other merged pull requests:** - feat: improve mime type definition [\#132](https://github.com/AntiMicroX/antimicrox/pull/132) ([Janfel](https://github.com/Janfel)) - docs: update building and installation instructions [\#129](https://github.com/AntiMicroX/antimicrox/pull/129) ([pktiuk](https://github.com/pktiuk)) - feat: antimicro config migration [\#120](https://github.com/AntiMicroX/antimicrox/pull/120) ([gombosg](https://github.com/gombosg)) ## [3.1.3](https://github.com/AntiMicroX/antimicrox/tree/3.1.3) (2020-11-15) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.1.2...3.1.3) **Fixed bugs:** - ARM build failure [\#80](https://github.com/AntiMicroX/antimicrox/issues/80) - AntiMicroX system tray icon not appearing in flatpak package [\#58](https://github.com/AntiMicroX/antimicrox/issues/58) - Icons in tray menu only showing up as "X" [\#56](https://github.com/AntiMicroX/antimicrox/issues/56) - Outdated information in the "Credits" tab in the "About" window [\#67](https://github.com/AntiMicroX/antimicrox/issues/67) **Notable closed issues:** - Consistent style of code [\#25](https://github.com/AntiMicroX/antimicrox/issues/25) **Other merged pull requests:** - Icons overhaul [\#73](https://github.com/AntiMicroX/antimicrox/pull/73) ([pktiuk](https://github.com/pktiuk)) - Fix: Use system icons in common cases to avoid incompatibility issues [\#62](https://github.com/AntiMicroX/antimicrox/pull/62) ([pktiuk](https://github.com/pktiuk)) - General cleanup of repository [\#18](https://github.com/AntiMicroX/antimicrox/pull/18) ([pktiuk](https://github.com/pktiuk)) ## [3.1.2](https://github.com/AntiMicroX/antimicrox/tree/3.1.2) (2020-10-02) [Full Changelog](https://github.com/AntiMicroX/antimicrox/compare/3.1.1...3.1.2) **Fixed bugs:** - Right click - Turbo and Clear not working properly [\#7](https://github.com/AntiMicroX/antimicrox/issues/7) - Wrong order for setting sets [\#6](https://github.com/AntiMicroX/antimicrox/issues/6) **Notable closed issues:** - Fedora resubmission [\#29](https://github.com/AntiMicroX/antimicrox/issues/29) - Flatpak packaging [\#9](https://github.com/AntiMicroX/antimicrox/issues/9) **Other merged pull requests:** - refactor: remove Dockerfiles [\#52](https://github.com/AntiMicroX/antimicrox/pull/52) ([gombosg](https://github.com/gombosg)) 2020-09-15 Gergely Gombos Version 3.1.1 - AppStream XML file revision - New screenshots - Add 128x128 icon - Prepare for Flathub submission 2020-09-09 Paweł Kotiuk Version 3.1.0 - Updated documentation connected with migration to new repository - Add instruction and config for building Flatpak packages - Gergely "gombosg" Gombos - Multiple improvements of packaging for Debian/Ubuntu - Ensure consistent naming across entire project - Rename used directories and files from antimicroX to antimicrox - First official AppImage release 2018-16-06 Jagoda Gorska Version 3.0.1 - Works with old antimicro profiles - Added small changes (in instructions, comments, etc.) - Added running in tray from right button Version 3.0 - Added qt directives for compatibility with older versions of qt5 - Arch Linux packages of application of frealgagu and sir_lucjan Link1: https://aur.archlinux.org/packages/antimicrox/ Link2: https://aur.archlinux.org/packages/antimicrox-git/ - Deb package of Paweł "pktiuk" Kotiuk Link1: https://github.com/pktiuk Link2: https://github.com/juliagoda/antimicroX/pull/120 Link3: https://github.com/juliagoda/antimicroX/pull/103 - Rpm package of Gergely "gombosg" Gombos meanwhile Link1: https://github.com/gombosg Link2: https://github.com/juliagoda/antimicroX/issues/118 - Created and added dockerfiles to containers - look README Link1: https://hub.docker.com/r/juliagoda/antimicrox - Changed icon for antimicroX - Added F13-F24 buttons to "Others" only if they are detected on keyboard - Added more adjusted debug/info/warning outputs to log settings - Added new functionality - joining and splitting slots - Added new functionality - deletion of more slots at once - Added new functionality - insertion of more slots at once - Added new functionality - One choice of execution paths and its arguments for multiple slots - Added new functionality - One choice of profile for multiple slots - Added new functionality - attaching numeric keypad keys thanks to option in settings - Added new functionality - global shortcuts for quitting application from settings - Added support for the same model of gamepads - Updated german, english and polish translation files # Fixed issue #92 - Fixed issue #97 - Fixed issue #90 - Fixed issue #98 - Fixed issue #101 - Fixed issue #107 - Fixed issue #108 - Fixed issue #109 - Fixed issue #113 - Fixed issue #112 - Fixed issue #114 - Fixed iisue #116 Version 2.25 - renamed AntiMicro into antimicroX - added detection of scripts - fixed unfinished JoyExecute slot - added menu icons and shortcuts - removed unused files and directives - removed majority of deprecated code - updated information about application - sorted and cleaned headers in header files - unlocked multiple parameters for command line - added notifications about battery level - added guard conditions Version 2.24.2 - Fixed bug with too many "emit propertyUpdated()" - Split JoyButtonSlot class into JoyButtonSlotXml and the original - Created template class for JoyDPad and VDPad xml - Split GameControllerDPad class into GameControllerDPadXml and the original - Replaced for loops with iterators and functional mappers - Replaced for loops with hashiterators - Added functions about vendor and product information - Changed guid to uniqueID Version 2.24.1 - Changed images and screenshots - Updated Documents (README, _.txt files, _.md, \*.mm files) - Updated resources - Created index.theme - Changed destination directories for icons, images, index.theme and other resources - Translated new text entries - Added detection of window partial title - Added reset settings option - Created smaller functions in part of classes - Split part of classes into new xml classes - Added com.github.juliagoda.antimicro.json for Flatpak (building and installation on Linux) - Cppcheck Analysis - fixed part of warnings - Added Comparing to nullptr instead of NULL and smart pointers - Changed if else to switch statements for int data types - First preparation for unit tests (app split into library (antilib) and executable (antimicro)) - Updated calibration - reset old values during calibration startup - Fixed part of memory leaks with Memcheck (application exit) - Fixed bug in gamecontrollermappingdialog class - Fixed segmentation fault for activating Turbo option - Unblocked delay sliders Version 2.24 - Added calibration - Ported Qt4 to Qt5 - Removed Qt4 support 2016-11-05 Jeff Backus Version 2.23 - Fixed portable version. (issue #37) - Added ability to specify logging level and file in config dialog. (issue #50) - Updated build system to find libraries on Windows systems instead of using explicit paths. (issue #43) - Added relevant window information to debug messages related to auto profiles. (issue #46) - Fixed issue with anything in profile name after first period being truncated. (issue #70) - Fixed issues with SDL 2.0.5 on all platforms. (issue #71) - Added support for additional small-case Latin characters when using Xtest. (issue #49) - Added inclusion of README-SDL.txt when building Windows distributables. 2016-07-30 Jeff Backus Version 2.22 - Fixed a segfault on startup issue affecting some Linux distributions - Fixed issues with SDL 2.0.4 on Windows. - Updated documentation and URLs in code to note transition in management. - Updated translations and added new ones. - Added code to revert all virtual buttons to beginning of slot list before a set switch. - Build system updates - Fixed a bug where invalid joystick was inserted into device list. - Modified to hide turbo mode combobox for regular buttons - Changed to allow blank config for auto profile entries again. - Fixed matching by process filename in AutoProfileWatcher 2016-01-10 Travis Nickles Version 2.21 - Changed unplug routine slightly. The old behavior was slightly wrong anyway but the old behavior did not work with SDL 2.0.4. - Custom Qt builds are being used for the 64 bit Windows build and noSSE Windows build. - Updated Windows build to use Qt 5.5.1. - Updated Windows build to use SDL 2.0.4. This should clear up a couple of problems for people running Windows 10. - Changes to some acceleration curves. Both the output values and the input offsets were changed to make mouse movement looser. - Removed First Run Wizard from program. In the end, that wizard was causing more problems for other users than it was worth. - Add arguments property for Execute slots. - Allow a real absolute mouse to be used with uinput support. Previously, relative mouse movement was being used to fake an absolute position for the mouse pointer. The WiimoteGlue project provided a way to allow uinput to send absolute mouse pointer events when using uinput. - Fixed set changing with analog triggers. 2015-10-19 Travis Nickles Version 2.20.2 - Change Enhanced Precision and Easing Quad/Cubic acceleration curves - Skipped straight to 2.20.2 since version 2.20 actually had 2.20.1 marked as its version in the application 2015-10-10 Travis Nickles Version 2.20 - Replace usage of QElapsedTimer with QTime for mouse movement calculations. - Start using Qt 5 with Ubuntu Vivid package. - Change XTest pointer acceleration when starting the program. - Allow release slot to have a 0 ms interval. This is useful for people who use a gamepad poll rate less than 10 ms. - Change minimize to tray code to work better with later versions of Gnome 3 and Unity. - Transfer travel distance axis changes when switching sets. 2015-09-29 Travis Nickles Version 2.19.3 - Japanese translation provided by tou omiya. - Make sure Game Controller Mapping dialog window reads raw joystick events. This should fix problems regarding improper mapping causing controller elements to no longer be mappable. - Make Set Change slots activate on button release instead of button press. - Tweaked the locking being performed in various portions of the program. - Fixed a problem with blank info window appearing when escaping from window capture utility dialog. - Fixed issues with document-save-as icon staying displayed after resetting a profile. - Fixed "Media Next" key binding for virtual keyboard. - Fixed various issues regarding binding slots in the Advanced Edit dialog window. 2015-09-15 Travis Nickles Version 2.19.2 - Add --next to allow multiple profiles to be loaded in one command call. - Add a flag to settings file when wizard is finished. Don't depend on any other settings being changed during an application run. - Fixed issue with inserting Pause slots. - Fixed issue with blank application filepath being matched for auto profile support. 2015-09-03 Travis Nickles Version 2.19.1 - Fixed SDL 1.2 build support. - Fixed issue with SDL thread not being stopped due to connections not being made in some situations. - Fixed loading of a profile from a second instance. - Fixed problem with main window not being populated after the App Settings Wizard was finished. - Fixed another portion of the program that assumed that a controller would be connected at startup. Fixes excessive CPU load. 2015-08-31 Travis Nickles Version 2.19 - Added curve options for extra acceleration. - Fixed bug when App Settings Wizard would pop up when not needed. - Simplified Chinese translation updated. 2015-08-24 Travis Nickles Version 2.18.2 - Fixed overly active timer used to reset acceleration distances when no events are returned from SDL in a given gamepad poll. - Sebian translation updated by Jay Alexander Fleming. - Changed behavior of 4 Way Cardinal mode for DPads. Diagonals are no longer counted as a dead zone. This change is more likely temporary. Up+Right - Up, Down+Right - Right, Down+Left - Down, Up+Left - Left 2015-08-18 Travis Nickles Version 2.18.1 - Fixed some threading issues when using X11. - Fixed excessive CPU load on startup when no controller is connected. 2015-08-15 Travis Nickles Version 2.18 - Perform event simulation in its own thread. Timer used for mouse speed calculations has improved as a result. - Slow down Enhanced Precision mouse acceleration curve slightly. Changes were mainly due to overall mouse emulation being tweaked. - Distributing 64 bit builds for Windows again. - Using a simulated event to click the minimize button in title bar now works on Windows. The move to using a dedicated thread for event simulation allows that to work now. - Simplified Chinese translation added thanks to zzpxyx. 2015-08-02 Travis Nickles Version 2.17 - Changed Enhanced Precision acceleration curve. The curve has been slowed down slightly. - Changed how initial mouse movement is performed when the gamepad poll rate and the mouse refresh rate differ. - Flash interface buttons after restoring the main window from the tray icon. - Tweaked mouse movement remainder routine. Remainders now only apply when the direction along an axis is the same. - Raised maximum cycle reset time to 60 seconds. - Fixed improper cycle reset interval. 2015-07-22 Travis Nickles Version 2.16 - Loosen initial mouse movement experienced after going outside the dead zone. - Added option in the mouse settings section that would allow antimicroX to reset the acceleration values being used for the uinput virtual mouse pointer. This is useful after playing older Linux games that change the acceleration settings for all mouse pointers after a game exits. Postal 2 and Doom 3 are two examples of games in my game library that exhibit this behavior. - Queue all events before performing any actions. The priority of various events has been changed as well. - Added option to change the gamepad poll rate used by the application. By default, the old 10 ms poll rate will be used. - Bundle a few backup icon files. Mainly useful on SteamOS since the themes used don't bundle a couple of essential icons that are expected to be present. - Compiled vmulti support into Windows build. The driver is not currently provided. The program needs to be started with the arguments --eventgen vmulti. - Temporarily stop packaging a 64 bit version of the program for Windows. Unfortunately, the version of Qt being used has a problem regarding timer accuracy that is not experienced with the 32 bit version of Qt being used. At this time, working around the problem is not feasible so there will be no 64 bit release. Please use the 32 bit version. - Change shortcuts used for the .msi package. - Bundle Qt translation files for Windows version. 2015-06-27 Travis Nickles Version 2.15 - Changed routine for extra acceleration for mouse movement. The new version is a bit faster and more responsive than the previous version. - Added release circle setting for spring mouse mode. This can be used to have the mouse return to a region around a character based on the last detected direction of an analog stick. - Added a sub-menu to the virtual keyboard. Some multimedia and browser keys can now be selected. - Added Execute slot type. A program can be set to launch when a slot is activated. - Added Text Entry slot type. You can now have a string of text typed when a slot is activated. This can be useful for inputting common commands in games. - Added proper interpolation to determine the start of diagonal regions of analog sticks. This is used for mouse movement in order to determine the proper starting dead zone point. - Changed Enhanced Precision mouse acceleration curve. The new changes in the curve should be much looser than before. - Fixed --unload command line option. Enforce reloading of config file when finished. - Fixed issue with spring mouse mode where the mouse would temporarily return to center when switching stick directions quickly. - Fixed some bindings in the virtual keyboard when using SendInput for the event generator. - Fixed issue with widgets used to update stick and dpad delay. The spinbox can now be used to edit the delay. - Reduced multiple instances of some objects. Reduces memory usage slightly. 2015-05-01 Travis Nickles Version 2.14 - Refactored extra axis acceleration. This revision uses individual gamepad polls again. Other changes in the code have made switching back feasible. With minor adjustments, the mouse will be looser but very controllable. - Added longer duration for extra axis acceleration. This allows extra acceleration to be performed over a period of time as opposed to just one gamepad poll. - Changed key repeat routine when using SendInput on Windows. Key releases restart the last active key repeat delay. - Now using Qt64-NG for the 64 bit Windows builds. - Initial experiments with vmulti support in the Windows version. Using that driver would allow antimicroX to use a virtual keyboard and mouse rather than using SendInput. That would allow antimicroX to work around UAC problems and anti-cheat programs. Support is not currently compiled into the Windows builds due to not being able to properly distribute the vmulti driver. - Do not write empty names tag in profiles if no custom button names have been specified. - Allow mouse history buffer size to go up to 100. - Allow diagonal range to go up to 90 degrees. - Remove old mouse speeds from mouse history buffer if stick has been returned to the dead zone. History buffer will be filled with zeroes. - Omit hotplugging dependent code when compiling against SDL 1.2. - Fixed dpad pointer bug when certain QueuedConnection slots are executed. 2015-03-31 Travis Nickles Version 2.13 - Updated extra axis acceleration routine. Now, extra acceleration is calculated after an axis has stopped moving past the assigned threshold in one gamepad poll. - Stick presets now change the diagonal range of a stick. This is mainly beneficial for mouse control changes so that 65 degrees is used by default. - Added a screen selector for Spring mouse mode in settings menu. - Added a small language selection portion to the settings menu. - Added a small logger. Please run antimicroX with "--log-level debug" in order to get output about button presses. 2015-03-22 Travis Nickles Version 2.12.1 - Implemented a small wizard that will be run when antimicroX is launched for the first time. It currently only has a page for editing some of the mouse settings and a page for associating antimicroX with .amgp files on Windows. - Show slots that are active for a stick modifier button on the main interface. The text for the main stick direction buttons will be prefixed with the currently active slots of the stick modifier button. - Corrected issue with stick and dpad events not getting activated on a set change. Events were being queued but not executed. 2015-03-15 Travis Nickles Version 2.12 - Added option for extra mouse acceleration. Enabling that option will increase the speed of the mouse based on the amount an axis has travelled in one gamepad poll and the set multiplier. This will greatly affect how the mouse behaves and it will make mouse movement looser. Using this feature can be problematic if the analog stick on your controller is worn out and loose. - Corrected issue with extra mouse sync events occurring when not needed (0,0 events). This change seems to have smoothed out mouse movement on the low end of an axis a bit. - Tweaked controller unplug workaround to still invoke release events for axes and buttons. For triggers, the release value is modified from what is provided by SDL so an unplug event will cause a release event to occur for the triggers. 2015-02-25 Travis Nickles Version 2.11.1 - Added workaround to allow gamepad unplugging on Windows to not activate bindings for the triggers. This was caused by the way controller unplugging is handled by SDL (primarily with the Windows version). SDL sends a release value for all elements of an unplugged joystick a brief period before sending the expected SDL_JOYDEVICEREMOVED event. The problem is that the released value used for triggers assumes that the dead zone is half the trigger's full range. This would cause bindings for triggers to usually activate for a brief period before SDL would send the final SDL_JOYDEVICEREMOVED event which would then deactivate those bindings. - Changes for the portable Windows version. Allow relative profile paths for use in the portable package on Windows. Associate profiles registry change prompt skipped. - Queue stick and dpad events. Allows for better control of 8-way sticks and dpads. 2015-02-07 Travis Nickles Version 2.11 - Adjusted the Enhanced Precision, Easing Quadratic, and Easing Cubic mouse acceleration curves. The low end of each curve has been loosened a bit and the rest of the curves have been adjusted accordingly. Comparing the two versions, the resulting mouse speed for a given axis point is slightly lower in the new versions for most of the curve. The extreme low end and the extreme high end of the curves will be slightly faster. - Updated Qt to version 5.4.0 for the Windows builds. - Compiled a 64 bit version for Windows thanks to the Qt-x64 project. - Added a set changing slot. - Added AppData for use when packaging on Linux thanks to Jeff Backus. - Fixed bug with mouse wheel event methods for axes which resulted in negative values being passed to the event timer. 2014-12-29 Travis Nickles Version 2.10.1 - Changed event handler fallback method under Linux. - Changed interface of Assignments page in Advanced Button Dialog. - Reset set number upon changing profiles. - Added "About Development" tab to About Dialog. - Fixed dynamic text resizing in Button Edit Dialog under Linux. - Fixed launching a second instance in order to load a profile in the first instance. 2014-12-10 Travis Nickles Version 2.10 - Changed allowed values for easing duration. The minimum value has been lowered to 0.0 and the maximum value has been increased to 5.0. - Added a stick modifier button. This button is primarily meant to be used to assign walk/run functionality to an analog stick. Instead of having to create distance zones and assign keyboard modifier keys to each stick button, you can now make the assignment on the stick modifier button and it will apply to the stick as a whole. It makes assigning walk/run functionality to an analog stick much less cumbersome. The DreadOut demo has already shown a use case where only the stick modifier button was needed due to the demo not handling running when using the left stick on an Xbox 360 controller. - Increased idle mouse timer interval to 100 ms. - Added a load profile slot. You can now tell the program to load a different profile upon pressing a button. - Added gradient functionality for the high end of the Easing Quadratic and Easing Cubic mouse acceleration curves. - Raise process priority on Windows. Now, the antimicroX process will run with High priority. This allows internal timers to work better and be less susceptible to the activity of other running programs. On Linux, the priority of the main thread has been increased. - Take multiple direction buttons into account when assigning set switching to stick buttons. - If uinput is enabled but not usable at runtime then XTest will be used as a fallback option for the Linux version. - Tweaked Gradient and Pulse turbo modes to make them a bit tighter. A lower delay will be needed in profiles to achieve a similar control from previous versions. On the plus side, this has been tested to work with FlatOut 2 fairly well. It is good enough to use and actually win some races against AI opponents. - Added analog control for mouse wheel buttons that are mapped to an axis button. - Tweaked mouse movement code to improve mouse accuracy. This is mainly due to discovering the QElapsedTimer class that is included in Qt. - Fixed middle mouse button binding when using the uinput event handler on Linux. - Fixed memory leaks that were discovered by Valgrind. 2014-11-19 Travis Nickles Version 2.9 - Added mouse refresh rate as an option. Please be mindful of how your system behaves if you set the refresh rate to a low value like 1 ms. In the worst case scenario, you could end up dedicating one CPU core on just the antimicroX process. Also, on Windows, you will want to make sure to disable the "Enhance Pointer Precision" option if you use a low value otherwise Windows will severely slow down the mouse pointer. - Added an application level mouse smoothing option. The older button level smoothing option has been removed. The old option didn't do much since it only dealt with the partial distance remainder. - Button responsiveness has been improved. The old mouse movement code was creating a bottleneck for button processing which would result in a slight delay. - Changed mouse movement code. The overall mouse movement should be smoother now. - Allow the Windows setting "Enhance Pointer Precision" to be disabled while antimicroX is running. This will make sure Windows does not directly manipulate the mouse events sent to the system. This will allow mouse control on an analog stick to be more accurate on Windows. - Changes to Auto Profile to allow more variables for matching. Multiple window properties can be specified which will cause antimicroX to count an entry as a match only if all specified properties match. - Changed how windows are grabbed in X on Linux. - Minor fix for Gradient and Pulse turbo modes. There were times when the timer interval controlling those modes could be negative and cause problems. 2014-11-05 Travis Nickles Version 2.8.1 - Fixed some buttons in virtual keyboard when program is using uinput support. - Fixed Update Joysticks option for SDL 1.2 users. 2014-10-28 Travis Nickles Version 2.8 - Added delay settings for analog sticks and dpads. This is meant to keep some games from overreacting when switching directions quickly. A delay is especially useful for games that utilize a dash on a key double tap. This will also be very useful while playing rougelike games. The new delay setting allows for more responsive controls than the old alternative of using hold zones on individual direction buttons. - Added two new mouse acceleration curves: Easing Quadratic and Easing Cubic. These new mouse acceleration curves are meant to mimic the camera control that is used for gamepad support in some recent first person shooters such as Borderlands 2. Once a stick direction has reached a threshold (80%) then the mouse speed will gradually accelerate over a period of time before the mouse speed reaches its peak. The duration of the easing method is set at 0.50 seconds by default but the setting is configurable per button. - Major refactor to mouse event generation. The new routine requires fewer system resources and it is more accurate. - Made uinput support a runtime option for Linux users. The program can now be compiled with both XTest and uinput support and the event generator can be specified using the --eventgen flag. It defaults to XTest if available. The option is only available when the program is compiled with both XTest and uinput support. - Added right click context menus for buttons in main interface. - Fixed issue with Game Controller Mapping dialog. Controller DPads that are exposed as 4 buttons can now be bound to the DPad of an SDL Game Controller. - Fixed an issue with incorrect profile names being displayed in the profile combobox. - Fixed issue introduced in version 2.7 regarding mouse movement calculations for the left direction of analog sticks. A major portion of the safe zone for that direction was being skipped. - Changed button groups in the main interface to update immediately when a stick or dpad mode has been changed. - Initial removal of old joystick abstraction support in interface when using SDL 2. 2014-10-14 Travis Nickles Version 2.7 - Added a UAC workaround for use in Windows. antimicroX can be restarted as Administrator in case a game is running with elevated permissions and the events generated by antimicroX are not detected by a game. - Added more key aliases for uinput support. - Force higher dead zones for axes in Game Controller Mapping window. - Fixed virtual keyboard in Button Edit Dialog window for Linux users utilizing XTest support. - Display some minor mouse stats in Mouse Settings dialog. - Alter Analog Stick dialog window to show some new stats. Also, show square stick coordinates as well as adjusted circle stick coordinates. - Added square stick to circle stick conversion. - Fixed issue with VK_LSHIFT and VK_RSHIFT aliases not being saved properly on Windows. - xinput is used for the uinput virtual pointer in order to disable mouse acceleration for the pointer. This allows spring mode to work as intended. - Added some code to guess which axes of a gamepad should be considered triggers by default while in old Joystick mode. The initial values of axes are taken from SDL and those are used as the point of the axes while centered. If the initial value of an axis is below -30,000 then an axis is considered to be a trigger. 2014-09-16 Travis Nickles Version 2.6 - Added two new Turbo modes. Gradient mode is used to change the key press time depending on the position of an axis (useful for racing games). Pulse mode is used to change how many times a key press is invoked depending on the position of an axis (scrolling in a web browser using arrow keys). - Fixed profile resetting in a couple of places. - A Russian translation has been provided by Dima Koshel. - Added option to invoke Game Controller mapping window from command line. The final mapping string will be printed to stdout. This is useful for saving a SDL_GAMECONTROLLERCONFIG for your controller that can be used system wide. Any SDL 2 game can then be set up to use that mapping and it can be changed if needed. - Profiles now use a unique .amgp file extension. Older xml profiles will continue to be supported. - Fixed spring mouse mode so that it uses proper axis distance values. - Set changing has been fixed for analog sticks and virtual dpads. - EXPERIMENTAL. uinput support has been added to the source code. Binary Linux packages will continue to utilize XTest for event generation for the time being. If you would like to test uinput integration then you will have to compile the program using -DWITH_UINPUT=ON and -DWITH_XTEST=OFF when running cmake. Playing Warsow 1.51 in Linux using antimicroX requires using uinput integration. Also, keys can now be pressed in a tty. 2014-08-01 Travis Nickles Version 2.5 - Fixed packaging the Windows version so the program will work on Windows XP again. - Delay rendering of flashing buttons. This helps improve controller responsiveness when the main window is not hidden. - Reduced the size of written profiles. Only changed values are now stored in profiles. - Updated German translation provided by phob and Leonard Koenig. - Allow a profile to be listed as the final argument on the command line. Ex: antimicroX ~/antimicroX-profiles/profile.xml. - Added diagonal distance support for distance slots for Standard mode on Sticks and DPads. This was necessary for some modifier assignments to work properly. The best example is for assigning walking in Half-Life 1. - Allow generated events to be sent to a different X display than the application is running on. This change was mainly done to better work with SteamOS. antimicroX can be run via ssh with X tunneling in order to configure profiles on one system but the program will send events to the X display that is running Steam and games. - Auto Profile support has improved for SteamOS. Application grabbing can now be done while in the SteamOS BPM Session. Steam BPM can be grabbed as well. - Only show active or soon to be active slots for buttons in the main window. The text displayed on the buttons will update when a new zone has been reached due to using slots such as distance or hold. - Allow no profile to be assigned to an application for an Auto Profile entry. This means that the program will choose an empty profile when the application for that Auto Profile entry has focus. This will help with disabling antimicro for applications that already have controller support. - Controller Mapping dialog now stops processing events until all elements have been released on a controller. 2014-05-30 Travis Nickles Version 2.4 - Relative spring mode added. - Key repeating changes in Windows. - Updated Windows version to use Qt 5.3.0. - Set copying added. - Corrected application checks used for Auto Profile support in Windows. 2014-05-23 Travis Nickles Version 2.3.3 - Tweaked Enhanced Precision mouse acceleration curve. - Tweaked "all" option in Auto Profile. No profile assigned to "all" now implies that a blank configuration should be loaded. - Manpage created by Jeff Backus. - Migrated to the CMake build system. 2014-05-15 Travis Nickles Version 2.3.2 - Fixed problem with old profiles not being usable in the program. 2014-05-13 Travis Nickles Version 2.3.1 - Added new Enhanced Precision mouse curve. It is now the default mouse curve. The new mouse curve will make the cursor move slowly towards the low end of an axis and the cursor movement will be accelerated towards the high end of an axis. - Added unsaved profile dialogs. - Added key repeating behavior under Windows. - Increased maximum turbo interval. - Added more options to the Edit Settings dialog. - Added profile name display editing. - Fixed invalid pointer issue for Hold events. 2014-05-02 Travis Nickles Version 2.3 - Added a daemon mode. - Added joystick profile compatibility parser for game controllers. Old profiles are now usable when using SDL Game Controller support. Old profiles have to be mapped against the same controller that is connected. - Added cycle reset support. Sequences with cycles can now get returned to the first cycle zone in a sequence after a period of time. - Changed Auto Profile support to work properly in SteamOS while running the SteamOS Big Picture Mode session. On many tested games (Duke Nukem 3D, SuperTux, World of Goo), the game had to be run in windowed mode in order for Auto Profile support to be able to detect the application. It is recommended that you run games in windowed mode when using Auto Profile support in the SteamOS BPM session. This is not an issue when running the Steam desktop client in desktop mode. - Added a delay slot type. A delay slot can be used for key presses in a key combination. Unlike other macro slots, slots placed before a delay slot will remain active after the specified time has passed. - Added option to allow the program to start on Windows startup. - Changed dialogs for secondary set buttons to display the set that the button is currently in. - Changed turbo mode to give more control. Key presses are now given more time to be active. Key presses and releases now run for a duration of t/2 seconds. - Altered tray menu to display a single list when only one controller is connected. An option has been added to allow for a single list to also be used when multiple controllers are detected. - Fixed issue with Windows XP Auto Profile workaround. On the plus side, now the program is confirmed to work in Windows XP. - Fixed issues with Auto Profile support saving and precedence. 2014-04-19 Travis Nickles Version 2.2 - Added example controller display to Game Controller Mapping dialog window. - Added Auto Profile support. Allows for profiles to be associated with specific applications. - Added button icons in Windows version. - Added a press time slot type. That slot type is used to have keys active for a specific period of time. - Allow Pause slots to have a 0 second interval. Allows for a forced key release. - Windows version is now built with SDL 2.0.3. - Fixed 8-Way D-Pad mode. - Fixed preset options in various dialogs to account for new aliases. - Fixed ampersand rendering in set buttons. - Fixed spring mouse mode dimension support. - Fixed spring mouse mode accuracy under Windows. 2014-02-28 Travis Nickles Version 2.1 - Added new stick and dpad modes. - Added set names. - Minor fixes for Windows. - Fixed QSettings usage to reduce reads and write to config file. 2014-02-10 Travis Nickles Version 2.0.1 - Active keyboard keys now use a reference count. This will be useful for keeping modifier keys held when moving a stick from a diagonal direction to a cardinal direction. This will allow a run to be maintained properly. - A release delay has been added to release slot events. This is needed for some games where a key press and release might happen too quickly for a game, such as The Elder Scrolls IV: Oblivion, to catch it. - Altered data sent to SendInput under Windows. The change should allow games that rely exclusively on scancode data to detect keyboard key presses now. Previously, keyboard emulation would not work while playing The Elder Scrolls IV: Oblivion on Windows. - Improved key associations under Windows. VK*OEM*\* keys associations are now generated at runtime which will allow associations to be more layout independent. - Changed some portions of the Windows version so that the Numpad Enter key can be emulated. - The recent profile list is now updated when a profile is added or removed from the list as opposed to when the program is closed. This allows the list to be in sync while utilizing hotplugging. 2014-01-04 Travis Nickles Version 2.0 - Migrated profiles to use Qt key values as opposed to using native key code values. Allows for better cross-platform compatibility. Current joystick profiles will be migrated when first loaded by the program. - Program can now be compiled against SDL 2. - The Game Controller API provided by SDL 2 has been integrated into the application. The API is used to abstract various gamepads to a unified standard. Profiles made against the Game Controller API can be used with any controller that is supported. Unsupported controllers will have to be mapped in the program. - A simple Game Controller mapping window has been made so people that are using an unsupported controller can map that controller so that it can be used with the Game Controller API. Any saved mapping string will be loaded into SDL when antimicro is first launched or when you select the "Update Joysticks" option in the main window. - Any new saved profile will include the device type that it is associated with in the filename. Joysticks and game controllers use slightly different file specifications. - Joystick hotplugging support has been added thanks to SDL 2. - On Windows, XInput support is now available. This allows the Xbox 360 controller guide button to be usable and both gamepad triggers can be used at the same time. Previously, only DirectInput was being used so both triggers were being mapped to one axis so they would negate each other if used at the same time. This problem would really affect people trying to play Call of Duty with a 360 controller when the "Hold Aim Down the Sight" option is enabled in the game. - The list of recent profiles is now tied to a joystick GUID or joystick name if the GUID is not available (compiled against SDL 1.2). - Program options window has been made. For right now, it is only being used to allow users to be able to disable Game Controller integration for specific controllers. - Mouse events are queued before a mouse event is sent to the system. This allows for smoother diagonal mouse movement. This really helped improve camera control for me in Warsow. - Key checker dialog has been made so you can check the alias values that are being used for keyboard keys. This is mainly for debugging purposes. If you find that a keyboard key that you use does not have a built-in alias, please let me know so an alias can be added. Although, the key can still be used in the program and saved to a profile. The major downside is that a profile that uses an unsupported key will not be cross-platform compatible. 2013-12-13 Travis Nickles Version 1.2 - Improved while held set changing so that the program should not get stuck on the wrong set. The changes made should behave roughly like the old while held workaround that used turbo. - Windows port of antimicro has been made. - Tweaked code used for button presses and releases in order to improve responsiveness. - Allow time-dependent action slots to have an interval as low as 0.01 seconds. - Tweaked Release action slot. Release slots can now be placed at the beginning of the assigned slots. This can be useful for Tap and Hold slot configurations. - Pause slots can now be used with Release slots. - Profiles can be removed from the recent configs list. - Spring mouse mode preview has now been enabled. - Mouse speed modifier action slot has been added. This can be used to modify the mouse speed settings used with any controller element while the slot is active. The setting will modify the mouse speed by the percentage that is specified. The mouse speed modifier can be used to allow for the mouse speed to be slowed down while sniping. - Button and action names have been added. Names can be used to describe the action that a slot sequence performs in the game. - Mouse wheel buttons are now used as a form of mouse movement. Mouse wheel scrolling is now possible without using turbo. The speed that the wheel is rotated can be specified in the mouse settings dialog window. - Added support for two extra mouse buttons. - A new controller properties window has been made. This window shows various bits of information provided by SDL about a controller as well as the current values of all the controller elements. - Added quick assign functionality for sticks and virtual dpads. - Windows version of the program now uses LocalAppData variable to know where to place the program's settings file. - New translations provided by the translation team. 2013-10-03 Travis Nickles Version 1.1 - Added spring mouse mode. This mode is used to move the mouse cursor from the center of the screen based on how much an axis has been moved from the dead zone. The mouse cursor will be returned to the center of the screen when the axis is released. - Added mouse curve options from QJoyPad. - Tweaked mouse movement in cursor mode to improve axis responsiveness and to allow mouse movement to be less jittery. - Added optional mouse smoothing for a further reduction in jitter in exchange for slightly delayed responsiveness. - Moved various mouse settings into a new dialog window. Several other dialog windows have been changed to point to the new dialog window to allow for mouse setting adjustments. - Added an option to start the program hidden. - Tray menu has been tweaked to allow configuration profiles to be disabled. A blank new profile will be enabled in the program for a controller. This is equivalent to selecting in the main window combobox. - Serbian translation provided by Jay Alexander Fleming. - Brazilian Portuguese translation provided by VaGNaroK. 2013-07-12 Travis Nickles Version 1.0 - 8-way controls have been implemented. This allows keys to be mapped to the diagonal directions of controller sticks and dpads. 8-way controls allow rougelike games to be playable. - Virtual Dpad support has been added. Axes and buttons can be mapped to a virtual dpad. This is useful for mapping dpads that are detected as a pair of axes in SDL. - A Quick Set option has been added. Using the Quick Set option, you can press a button on the controller and the program will bring up the edit window for that specific button. The button can then be mapped to an assignment from the edit window. The Quick Set option also works for axes, controller sticks, and dpads. This is more of a convenience function than anything but I have found it really useful since implementing it. - Main interface button text is now updated whenever the assigned slots are changed. This allows the buttons' text to be in sync in many situations that was not possible before. - Toggle and Turbo can be used together to create automated key macros for use in MMORPGs. \* _This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)_ AntiMicroX-antimicrox-b300273/CMakeLists.txt000066400000000000000000001026621471077622000207210ustar00rootroot00000000000000## antimicrox Gamepad to KB+M event mapper ## Copyright (C) 2015 Travis Nickles ## Copyright (C) 2020 Jagoda Górska ## Copyright (C) 2020 Paweł Kotiuk ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . cmake_minimum_required(VERSION 3.12) project(antimicrox) if(POLICY CMP0071) cmake_policy(SET CMP0071 NEW) endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" "${CMAKE_ROOT}/Modules") set(CMAKE_INCLUDE_CURRENT_DIR ON) if(UNIX AND NOT APPLE AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "force cmake prefix to be set for /usr" FORCE) endif(UNIX AND NOT APPLE AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) include(CheckCXXCompilerFlag) include(GNUInstallDirs) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) message("Build type: ${CMAKE_BUILD_TYPE}") if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" AND MSVC_TOOLSET_VERSION GREATER_EQUAL 141) set(COMPILER_IS_MSVC TRUE) endif() if(NOT COMPILER_IS_MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -Wextra") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wcast-align -Wunreachable-code -g -O0 -fno-omit-frame-pointer") # ADDITIONAL DEBUG FLAGS # set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wstrict-null-sentinel -Wstrict-overflow=5 -Wundef -Wno-unused -Wswitch-enum") if(UNIX AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -rdynamic") endif(UNIX AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /analyze- /D_CRT_SECURE_NO_WARNINGS") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W3 /GS /Od /sdl /wd4996 /RTC1 /Gd /Oy- /permissive-") endif(NOT COMPILER_IS_MSVC) # The version number. set(ANTIMICROX_MAJOR_VERSION 3) set(ANTIMICROX_MINOR_VERSION 5) set(ANTIMICROX_PATCH_VERSION 0) if(UNIX) option(WITH_X11 "Compile with support for X11." ON) option(WITH_UINPUT "Compile with support for uinput. uinput will be usable to simulate events." ON) option(INSTALL_UINPUT_UDEV_RULES "Generate udev rules allowing users using uinput without root permissions." ON) option(WITH_XTEST "Compile with support for XTest. XTest will be usable to simulate events." ON) option(APPDATA "Build project with AppData file support." ON) endif(UNIX) if(WIN32) option(PORTABLE_WIN "Compile app for portability" OFF) endif(WIN32) option(USE_QT6_BY_DEFAULT "Use Qt6 if available (if not available fallback to QT5)" OFF) option(UPDATE_TRANSLATIONS "Call lupdate to update translation files from source." OFF) option(TRANS_REMOVE_OBSOLETE "Add -noobsolete option to lupdate command to get rid of old text entries" OFF) option(ATTACH_FAKE_CLASSES "Fake classes can be used in application to tests functionalities" OFF) option(ANTIMICROX_PKG_VERSION "Manually define version of package displayed in info tab" OFF) option(CHECK_FOR_UPDATES "Enable checking for updates using GitHub REST API." OFF) option(BUILD_DOCS "Build documentation" OFF) option(WITH_TESTS "Allow tests for classes" OFF) if(WITH_TESTS) message("Tests enabled") endif(WITH_TESTS) if(ANTIMICROX_PKG_VERSION) message("This build will be marked as: ${ANTIMICROX_PKG_VERSION}") add_compile_definitions(ANTIMICROX_PKG_VERSION="${ANTIMICROX_PKG_VERSION}") endif(ANTIMICROX_PKG_VERSION) if(CHECK_FOR_UPDATES) message("This build will check for updates using GitHub API.") add_compile_definitions(CHECK_FOR_UPDATES="${CHECK_FOR_UPDATES}") endif(CHECK_FOR_UPDATES) if(UNIX) if(WITH_XTEST AND NOT WITH_X11) set(WITH_XTEST OFF) message("Cannot use XTest without X11. Disabling XTest support.") endif(WITH_XTEST AND NOT WITH_X11) if(WITH_XTEST) message("XTest support allowed for simulating events.") endif(WITH_XTEST) if(WITH_UINPUT) message("uinput support allowed for simulating events.") else() set(INSTALL_UINPUT_UDEV_RULES OFF) endif(WITH_UINPUT) if(NOT WITH_XTEST AND NOT WITH_UINPUT) message(FATAL_ERROR "No system is defined for simulating events.") endif(NOT WITH_XTEST AND NOT WITH_UINPUT) endif(UNIX) ############################### # PLATFORM-INDEPENDENT FILES ############################### set(antimicrox_MAIN src/main.cpp) set(antimicrox_SOURCES src/antimicrosettings.cpp src/antkeymapper.cpp src/applaunchhelper.cpp src/autoprofileinfo.cpp src/axisvaluebox.cpp src/commandlineutility.cpp src/common.cpp src/dpadcontextmenu.cpp src/dpadpushbutton.cpp src/dpadpushbuttongroup.cpp src/event.cpp src/eventhandlerfactory.cpp src/eventhandlers/baseeventhandler.cpp src/gamecontroller/gamecontroller.cpp src/gamecontroller/gamecontrollerdpad.cpp src/gamecontroller/gamecontrollerset.cpp src/gamecontroller/gamecontrollertrigger.cpp src/gamecontroller/gamecontrollertriggerbutton.cpp src/gamecontrollerexample.cpp src/globalvariables.cpp src/gui/aboutdialog.cpp src/gui/addeditautoprofiledialog.cpp src/gui/advancebuttondialog.cpp src/gui/advancestickassignmentdialog.cpp src/gui/axiseditdialog.cpp src/gui/buttoneditdialog.cpp src/gui/calibration.cpp src/gui/dpadeditdialog.cpp src/gui/editalldefaultautoprofiledialog.cpp src/gui/extraprofilesettingsdialog.cpp src/gui/flashbuttonwidget.cpp src/gui/gamecontrollermappingdialog.cpp src/gui/joyaxiswidget.cpp src/gui/joybuttonwidget.cpp src/gui/joycontrolstickeditdialog.cpp src/gui/joydpadbuttonwidget.cpp src/gui/joysensoreditdialog.cpp src/gui/joystickstatuswindow.cpp src/gui/joytabwidget.cpp src/gui/joytabwidgetcontainer.cpp src/gui/mainsettingsdialog.cpp src/gui/mainwindow.cpp src/gui/mousesettingsdialog.cpp src/gui/qkeydisplaydialog.cpp src/gui/quicksetdialog.cpp src/gui/setaxisthrottledialog.cpp src/gui/setnamesdialog.cpp src/gui/slotitemlistwidget.cpp src/haptictriggerps5.cpp src/inputdaemon.cpp src/inputdevice.cpp src/inputdevicebitarraystatus.cpp src/inputdevicecalibration.cpp src/joyaccelerometersensor.cpp src/joyaxis.cpp src/joyaxiscontextmenu.cpp src/joybuttoncontextmenu.cpp src/joybuttonmousehelper.cpp src/joybuttonslot.cpp src/joybuttonstatusbox.cpp src/joybuttontypes/joybutton.cpp src/joybuttontypes/joyaccelerometerbutton.cpp src/joybuttontypes/joyaxisbutton.cpp src/joybuttontypes/joycontrolstickbutton.cpp src/joybuttontypes/joycontrolstickmodifierbutton.cpp src/joybuttontypes/joydpadbutton.cpp src/joybuttontypes/joygradientbutton.cpp src/joybuttontypes/joygyroscopebutton.cpp src/joybuttontypes/joysensorbutton.cpp src/joycontrolstick.cpp src/joycontrolstickbuttonpushbutton.cpp src/joycontrolstickcontextmenu.cpp src/joycontrolstickpushbutton.cpp src/joycontrolstickstatusbox.cpp src/joydpad.cpp src/joygyroscopesensor.cpp src/joysensor.cpp src/joysensorbuttonpushbutton.cpp src/joysensorcontextmenu.cpp src/joysensorfactory.cpp src/joysensorpreset.cpp src/joysensorpushbutton.cpp src/joysensorstatusbox.cpp src/joystick.cpp src/keyboard/virtualkeyboardmousewidget.cpp src/keyboard/virtualkeypushbutton.cpp src/keyboard/virtualmousepushbutton.cpp src/localantimicroserver.cpp src/logger.cpp src/mousedialog/mouseaxissettingsdialog.cpp src/mousedialog/mousebuttonsettingsdialog.cpp src/mousedialog/mousecontrolsticksettingsdialog.cpp src/mousedialog/mousedpadsettingsdialog.cpp src/mousedialog/mousesensorsettingsdialog.cpp src/mousedialog/springmoderegionpreview.cpp src/mousedialog/uihelpers/mouseaxissettingsdialoghelper.cpp src/mousedialog/uihelpers/mousebuttonsettingsdialoghelper.cpp src/mousedialog/uihelpers/mousecontrolsticksettingsdialoghelper.cpp src/mousedialog/uihelpers/mousedpadsettingsdialoghelper.cpp src/mousehelper.cpp src/pt1filter.cpp src/qtkeymapperbase.cpp src/sdleventreader.cpp src/sensorpushbuttongroup.cpp src/setjoystick.cpp src/simplekeygrabberbutton.cpp src/statisticsestimator.cpp src/stickpushbuttongroup.cpp src/uihelpers/advancebuttondialoghelper.cpp src/uihelpers/buttoneditdialoghelper.cpp src/uihelpers/dpadcontextmenuhelper.cpp src/uihelpers/dpadeditdialoghelper.cpp src/uihelpers/gamecontrollermappingdialoghelper.cpp src/uihelpers/joyaxiscontextmenuhelper.cpp src/uihelpers/joycontrolstickcontextmenuhelper.cpp src/uihelpers/joycontrolstickeditdialoghelper.cpp src/uihelpers/joysensoriothreadhelper.cpp src/uihelpers/joytabwidgethelper.cpp src/vdpad.cpp src/xml/inputdevicexml.cpp src/xml/joyaxisxml.cpp src/xml/joybuttonslotxml.cpp src/xml/joybuttonxml.cpp src/xml/joydpadxml.cpp src/xml/setjoystickxml.cpp src/xmlconfigmigration.cpp src/xmlconfigreader.cpp src/xmlconfigwriter.cpp ) set(antimicrox_HEADERS src/antimicrosettings.h src/antkeymapper.h src/applaunchhelper.h src/autoprofileinfo.h src/axisvaluebox.h src/commandlineutility.h src/dpadcontextmenu.h src/dpadpushbutton.h src/dpadpushbuttongroup.h src/eventhandlerfactory.h src/eventhandlers/baseeventhandler.h src/gamecontroller/gamecontroller.h src/gamecontroller/gamecontrollerdpad.h src/gamecontroller/gamecontrollerset.h src/gamecontroller/gamecontrollertrigger.h src/gamecontroller/gamecontrollertriggerbutton.h src/gamecontroller/xml/gamecontrollerdpadxml.h src/gamecontroller/xml/gamecontrollertriggerxml.h src/gamecontroller/xml/gamecontrollerxml.h src/gamecontrollerexample.h src/globalvariables.h src/gui/aboutdialog.h src/gui/addeditautoprofiledialog.h src/gui/advancebuttondialog.h src/gui/advancestickassignmentdialog.h src/gui/axiseditdialog.h src/gui/buttoneditdialog.h src/gui/calibration.h src/gui/dpadeditdialog.h src/gui/editalldefaultautoprofiledialog.h src/gui/extraprofilesettingsdialog.h src/gui/flashbuttonwidget.h src/gui/gamecontrollermappingdialog.h src/gui/joyaxiswidget.h src/gui/joybuttonwidget.h src/gui/joycontrolstickeditdialog.h src/gui/joydpadbuttonwidget.h src/gui/joysensoreditdialog.h src/gui/joystickstatuswindow.h src/gui/joytabwidget.h src/gui/joytabwidgetcontainer.h src/gui/mainsettingsdialog.h src/gui/mainwindow.h src/gui/mousesettingsdialog.h src/gui/qkeydisplaydialog.h src/gui/quicksetdialog.h src/gui/setaxisthrottledialog.h src/gui/setnamesdialog.h src/gui/slotitemlistwidget.h src/haptictriggerps5.h src/haptictriggermodeps5.h src/inputdaemon.h src/inputdevice.h src/inputdevicebitarraystatus.h src/inputdevicecalibration.h src/joyaccelerometersensor.h src/joyaxis.h src/joyaxiscontextmenu.h src/joybuttoncontextmenu.h src/joybuttonmousehelper.h src/joybuttonslot.h src/joybuttonstatusbox.h src/joybuttontypes/joybutton.h src/joybuttontypes/joyaccelerometerbutton.h src/joybuttontypes/joyaxisbutton.h src/joybuttontypes/joycontrolstickbutton.h src/joybuttontypes/joycontrolstickmodifierbutton.h src/joybuttontypes/joydpadbutton.h src/joybuttontypes/joygradientbutton.h src/joybuttontypes/joygyroscopebutton.h src/joybuttontypes/joysensorbutton.h src/joycontrolstick.h src/joycontrolstickbuttonpushbutton.h src/joycontrolstickcontextmenu.h src/joycontrolstickpushbutton.h src/joycontrolstickstatusbox.h src/joydpad.h src/joygyroscopesensor.h src/joysensor.h src/joysensorbuttonpushbutton.h src/joysensorcontextmenu.h src/joysensordirection.h src/joysensorfactory.h src/joysensorpreset.h src/joysensorpushbutton.h src/joysensorstatusbox.h src/joysensortype.h src/joystick.h src/keyboard/virtualkeyboardmousewidget.h src/keyboard/virtualkeypushbutton.h src/keyboard/virtualmousepushbutton.h src/localantimicroserver.h src/logger.h src/mousedialog/mouseaxissettingsdialog.h src/mousedialog/mousebuttonsettingsdialog.h src/mousedialog/mousecontrolsticksettingsdialog.h src/mousedialog/mousedpadsettingsdialog.h src/mousedialog/springmoderegionpreview.h src/mousedialog/mousesensorsettingsdialog.h src/mousedialog/uihelpers/mouseaxissettingsdialoghelper.h src/mousedialog/uihelpers/mousebuttonsettingsdialoghelper.h src/mousedialog/uihelpers/mousecontrolsticksettingsdialoghelper.h src/mousedialog/uihelpers/mousedpadsettingsdialoghelper.h src/mousehelper.h src/pt1filter.h src/qtkeymapperbase.h src/sdleventreader.h src/sensorpushbuttongroup.h src/setjoystick.h src/simplekeygrabberbutton.h src/statisticsestimator.h src/stickpushbuttongroup.h src/uihelpers/advancebuttondialoghelper.h src/uihelpers/buttoneditdialoghelper.h src/uihelpers/dpadcontextmenuhelper.h src/uihelpers/dpadeditdialoghelper.h src/uihelpers/gamecontrollermappingdialoghelper.h src/uihelpers/joyaxiscontextmenuhelper.h src/uihelpers/joycontrolstickcontextmenuhelper.h src/uihelpers/joycontrolstickeditdialoghelper.h src/uihelpers/joysensoriothreadhelper.h src/uihelpers/joytabwidgethelper.h src/vdpad.h src/xml/inputdevicexml.h src/xml/joyaxisxml.h src/xml/joybuttonslotxml.h src/xml/joybuttonxml.h src/xml/joydpadxml.h src/xml/setjoystickxml.h src/xmlconfigmigration.h src/xmlconfigreader.h src/xmlconfigwriter.h ) if(ATTACH_FAKE_CLASSES) LIST(APPEND antimicrox_SOURCES src/fakeclasses/xbox360wireless.cpp ) LIST(APPEND antimicrox_HEADERS src/fakeclasses/xbox360wireless.h ) endif(ATTACH_FAKE_CLASSES) set(antimicrox_FORMS src/gui/aboutdialog.ui src/gui/addeditautoprofiledialog.ui src/gui/advancebuttondialog.ui src/gui/advancestickassignmentdialog.ui src/gui/axiseditdialog.ui src/gui/buttoneditdialog.ui src/gui/calibration.ui src/gui/capturedwindowinfodialog.ui src/gui/dpadeditdialog.ui src/gui/editalldefaultautoprofiledialog.ui src/gui/extraprofilesettingsdialog.ui src/gui/gamecontrollermappingdialog.ui src/gui/joycontrolstickeditdialog.ui src/gui/joysensoreditdialog.ui src/gui/joystickstatuswindow.ui src/gui/mainsettingsdialog.ui src/gui/mainwindow.ui src/gui/mousesettingsdialog.ui src/gui/qkeydisplaydialog.ui src/gui/quicksetdialog.ui src/gui/setaxisthrottledialog.ui src/gui/setnamesdialog.ui ) set(antimicrox_RESOURCES src/resources.qrc) ############################### # PLATFORM-DEPENDENT FILES ############################### if(UNIX) if(WITH_X11) LIST(APPEND antimicrox_SOURCES src/x11extras.cpp src/qtx11keymapper.cpp src/unixcapturewindowutility.cpp src/autoprofilewatcher.cpp src/gui/capturedwindowinfodialog.cpp ) LIST(APPEND antimicrox_HEADERS src/x11extras.h src/qtx11keymapper.h src/unixcapturewindowutility.h src/autoprofilewatcher.h src/gui/capturedwindowinfodialog.h ) if(WITH_XTEST) LIST(APPEND antimicrox_SOURCES src/eventhandlers/xtesteventhandler.cpp) LIST(APPEND antimicrox_HEADERS src/eventhandlers/xtesteventhandler.h) endif(WITH_XTEST) endif(WITH_X11) if(WITH_UINPUT) LIST(APPEND antimicrox_SOURCES src/qtuinputkeymapper.cpp src/uinputhelper.cpp src/eventhandlers/uinputeventhandler.cpp ) LIST(APPEND antimicrox_HEADERS src/qtuinputkeymapper.h src/uinputhelper.h src/eventhandlers/uinputeventhandler.h ) endif(WITH_UINPUT) elseif(WIN32) LIST(APPEND antimicrox_SOURCES src/autoprofilewatcher.cpp src/winextras.cpp src/qtwinkeymapper.cpp src/gui/winappprofiletimerdialog.cpp src/gui/capturedwindowinfodialog.cpp src/eventhandlers/winsendinputeventhandler.cpp src/joykeyrepeathelper.cpp ) LIST(APPEND antimicrox_HEADERS src/autoprofilewatcher.h src/winextras.h src/qtwinkeymapper.h src/gui/winappprofiletimerdialog.h src/gui/capturedwindowinfodialog.h src/eventhandlers/winsendinputeventhandler.h src/joykeyrepeathelper.h ) LIST(APPEND antimicrox_FORMS src/gui/winappprofiletimerdialog.ui ) endif(UNIX) ############################### # DEFINITIONS ############################### if(UNIX) if(WITH_X11) add_definitions(-DWITH_X11) endif(WITH_X11) if(WITH_XTEST) add_definitions(-DWITH_XTEST) endif(WITH_XTEST) if(WITH_UINPUT) add_definitions(-DWITH_UINPUT) endif(WITH_UINPUT) endif(UNIX) ############################### # REQUIRED PACKAGES ############################### #QT set(QT_REQUIRED_VERSION 5.10) set(CMAKE_AUTOMOC TRUE) # required by moc preprocessor used in QT if(USE_QT6_BY_DEFAULT) find_package(Qt6 COMPONENTS Core) if(NOT Qt6_FOUND) message("QT6 not found. Falling back to QT5.") endif() else() find_package(Qt5 COMPONENTS Core) if(NOT Qt5_FOUND) message("QT5 not found. Falling back to QT6.") endif() endif() if (Qt6_FOUND OR NOT Qt5_FOUND) find_package(Qt6 ${QT_REQUIRED_VERSION} COMPONENTS Core Widgets Gui Network LinguistTools Concurrent REQUIRED) find_package(QT NAMES Qt6 REQUIRED) # used to get version number in QT_VERSION_MAJOR and QT_VERSION QT_WRAP_UI(antimicrox_FORMS_HEADERS ${antimicrox_FORMS}) QT_ADD_RESOURCES(antimicrox_RESOURCES_RCC ${antimicrox_RESOURCES}) else() find_package(Qt5 ${QT_REQUIRED_VERSION} COMPONENTS Core Widgets Gui Network LinguistTools Concurrent REQUIRED) find_package(QT NAMES Qt5 REQUIRED) # used to get version number in QT_VERSION_MAJOR and QT_VERSION QT5_WRAP_UI(antimicrox_FORMS_HEADERS ${antimicrox_FORMS}) QT5_ADD_RESOURCES(antimicrox_RESOURCES_RCC ${antimicrox_RESOURCES}) endif() message("Found QT: ${QT_VERSION}") add_subdirectory("share/antimicrox/translations") set(CMAKE_POSITION_INDEPENDENT_CODE ON) # SDL set(SDL_REQUIRED_VERSION 2.0.6) find_package(SDL2 REQUIRED) # Others if(WITH_X11) find_package(X11 REQUIRED) endif(WITH_X11) ############################### # LINKER LIBRARIES ############################### LIST(APPEND QT_LIBS Qt${QT_VERSION_MAJOR}::Core) LIST(APPEND QT_LIBS Qt${QT_VERSION_MAJOR}::Gui) LIST(APPEND QT_LIBS Qt${QT_VERSION_MAJOR}::Widgets) LIST(APPEND QT_LIBS Qt${QT_VERSION_MAJOR}::Concurrent) LIST(APPEND QT_LIBS Qt${QT_VERSION_MAJOR}::Network) if(UNIX) if(WITH_X11) LIST(APPEND X11_LIBS ${X11_X11_LIB}) LIST(APPEND X11_LIBS ${X11_Xi_LIB}) endif(WITH_X11) if(WITH_XTEST) LIST(APPEND EXTRA_LIBS ${X11_XTest_LIB}) endif(WITH_XTEST) # necessary ifwe use find_package for SDL2 # if(NOT DEFINED SDL2_LIBRARIES) # set(SDL2_LIBRARIES SDL2::SDL2) # endif() elseif (WIN32) list(APPEND WIN_LIBS "psapi") endif(UNIX) include_directories( ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_CURRENT_BINARY_DIR}/src" ${PROJECT_SOURCE_DIR} "${PROJECT_SOURCE_DIR}/src" "${PROJECT_SOURCE_DIR}/src/gui" ${SDL2_INCLUDE_DIRS} ) # Store executable in a bin subdir. Needed here so translations can be loaded. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") ############################### # COMPILE & LINK ############################### if(UNIX) add_executable(antimicrox ${antimicrox_MAIN} ${antimicrox_HEADERS_MOC} ${antimicrox_SOURCES} ${antimicrox_FORMS_HEADERS} ${antimicrox_RESOURCES_RCC} ) elseif(WIN32) # The WIN32 is required to specify a GUI application. add_executable(antimicrox WIN32 ${antimicrox_MAIN} ${antimicrox_HEADERS_MOC} ${antimicrox_SOURCES} ${antimicrox_FORMS_HEADERS} ${antimicrox_RESOURCES_RCC} src/antimicrox_windows_icon.rc # Embedding icon into Windows executable ) target_link_libraries(antimicrox ${WIN_LIBS} ) if(PORTABLE_WIN) add_definitions(-DWIN_PORTABLE_PACKAGE) endif() endif(UNIX) target_link_libraries(antimicrox ${QT_LIBS} ${X11_LIBS} ${SDL2_LIBRARIES} ${EXTRA_LIBS} ) target_include_directories(antimicrox PUBLIC ${SDL2_INCLUDE_DIRS}/SDL2 ) ############################### # INSTALL ############################### # Specify out directory for final executable. install(TARGETS antimicrox RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") if(UNIX) find_package(ECM REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_DIR}) include(ECMInstallIcons) ecm_install_icons(ICONS share/icons/application/16x16/apps/16-apps-io.github.antimicrox.antimicrox.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons) ecm_install_icons(ICONS share/icons/application/24x24/apps/24-apps-io.github.antimicrox.antimicrox.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons) ecm_install_icons(ICONS share/icons/application/32x32/apps/32-apps-io.github.antimicrox.antimicrox.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons) ecm_install_icons(ICONS share/icons/application/48x48/apps/48-apps-io.github.antimicrox.antimicrox.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons) ecm_install_icons(ICONS share/icons/application/64x64/apps/64-apps-io.github.antimicrox.antimicrox.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons) ecm_install_icons(ICONS share/icons/application/128x128/apps/128-apps-io.github.antimicrox.antimicrox.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons) ecm_install_icons(ICONS share/icons/application/scalable/apps/sc-apps-io.github.antimicrox.antimicrox.svg DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons) ecm_install_icons(ICONS share/icons/breeze_themed/48-apps-antimicrox_trayicon.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons THEME breeze) ecm_install_icons(ICONS src/images/48-apps-antimicrox_trayicon.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons) install(FILES CHANGELOG.md DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/doc/antimicrox") install(FILES other/io.github.antimicrox.antimicrox.desktop DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications") install(FILES other/io.github.antimicrox.antimicrox.xml DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/mime/packages") # Copy current Changelog file to location that the resource file expects. install(FILES CHANGELOG.md DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/antimicrox") endif(UNIX) # Add man page for *nix platforms. if(UNIX) add_subdirectory(other) # Only way to force install target to be dependent on manpage. install(CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} manpage WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")") if(APPDATA) # Only way to force install target to be dependent on appdata. install(CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} appdata WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")") endif(APPDATA) endif(UNIX) if(UNIX) if(INSTALL_UINPUT_UDEV_RULES) message("Udev rules installation enabled.") install(FILES other/60-antimicrox-uinput.rules DESTINATION "/usr/lib/udev/rules.d/") endif(INSTALL_UINPUT_UDEV_RULES) endif(UNIX) # Copy libraries needed by Windows if(WIN32) add_custom_command(TARGET antimicrox POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "dll files linked with antimicrox executable: $ " COMMAND_EXPAND_LISTS ) add_custom_command(TARGET antimicrox POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ $ COMMAND_EXPAND_LISTS ) find_path(SDL2_DLL_LOCATION_DIR "SDL2.dll" HINTS "${SDL2_LIBRARY_DIRS}/../bin") #these three lines assume SDL2 in standard location TODO do it better find_path(GCC_DLL "libgcc_s_seh-1.dll" HINTS "${SDL2_LIBRARY_DIRS}/../bin") find_path(PTHREAD_DLL_DIR "libwinpthread-1.dll" HINTS "${SDL2_LIBRARY_DIRS}/../bin") find_path(LIBCPP_DLL_DIR "libstdc++-6.dll" HINTS "${SDL2_LIBRARY_DIRS}/../bin") list(APPEND DLL_FILES "${CMAKE_CURRENT_BINARY_DIR}/bin/Qt${QT_VERSION_MAJOR}Core.dll" "${CMAKE_CURRENT_BINARY_DIR}/bin/Qt${QT_VERSION_MAJOR}Gui.dll" "${CMAKE_CURRENT_BINARY_DIR}/bin/Qt${QT_VERSION_MAJOR}Concurrent.dll" "${CMAKE_CURRENT_BINARY_DIR}/bin/Qt${QT_VERSION_MAJOR}Network.dll" "${CMAKE_CURRENT_BINARY_DIR}/bin/Qt${QT_VERSION_MAJOR}Widgets.dll" "${SDL2_DLL_LOCATION_DIR}/SDL2.dll" "${GCC_DLL}/libgcc_s_seh-1.dll" "${PTHREAD_DLL_DIR}/libwinpthread-1.dll" "${LIBCPP_DLL_DIR}/libstdc++-6.dll" ) if(QT_VERSION_MAJOR EQUAL 5) list(APPEND DLL_FILES "${CMAKE_CURRENT_BINARY_DIR}/bin/libEGL.dll" ) endif(QT_VERSION_MAJOR EQUAL 5) if(CHECK_FOR_UPDATES) message("Searching for SSL DLL-s.") find_path(LIBCRYPTO_DLL_DIR "libcrypto-1_1-x64.dll" HINTS "${SDL2_LIBRARY_DIRS}/../bin") find_path(LIBSSL_DLL_DIR "libssl-1_1-x64.dll" HINTS "${SDL2_LIBRARY_DIRS}/../bin") list(APPEND DLL_FILES "${LIBCRYPTO_DLL_DIR}/libcrypto-1_1-x64.dll" "${LIBSSL_DLL_DIR}/libssl-1_1-x64.dll" ) endif(CHECK_FOR_UPDATES) install(FILES ${DLL_FILES} TYPE BIN ) # Required platform plugin get_target_property(QtCore_LOCATION Qt${QT_VERSION_MAJOR}::Core LOCATION) get_filename_component(QT_DLL_DIR ${QtCore_LOCATION} PATH) install(FILES ${QT_DLL_DIR}/../plugins/platforms/qwindows.dll DESTINATION ./bin/platforms/) endif(WIN32) # uninstall target configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) # Only way to force install target to be dependent on updateqm. install(CODE "execute_process(COMMAND ${CMAKE_BUILD_TOOL} updateqm WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")") # Use this to use some variables created here in the actual project. # Modify the config.h.in file using the appropriate variables. configure_file( "${PROJECT_SOURCE_DIR}/src/config.h.in" "${PROJECT_BINARY_DIR}/config.h" ) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/CHANGELOG.md DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/src/) if(WITH_TESTS) enable_testing() add_subdirectory(tests) endif(WITH_TESTS) # Install SDL database with linked License file if(UNIX) install(FILES share/gamecontrollerdb_linux.txt DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/antimicrox/" RENAME gamecontrollerdb.txt) elseif(WIN32) install(FILES share/gamecontrollerdb_windows.txt DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/antimicrox/" RENAME gamecontrollerdb.txt) endif(UNIX) install(FILES share/LICENSE_SDL_GameControllerDB DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/antimicrox/") ############################### # PACKAGES BUILDING WITH CPACK ############################### include(InstallRequiredSystemLibraries) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Program used to map keyboard keys and mouse controls to a gamepad.") set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/AntiMicroX/antimicrox/") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set(CPACK_PACKAGE_VERSION_MAJOR "${ANTIMICROX_MAJOR_VERSION}") set(CPACK_PACKAGE_VERSION_MINOR "${ANTIMICROX_MINOR_VERSION}") set(CPACK_PACKAGE_VERSION_PATCH "${ANTIMICROX_PATCH_VERSION}") if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(CPACK_PACKAGE_VERSION_PATCH "${CPACK_PACKAGE_VERSION_PATCH}-dbg") endif() set(CPACK_PACKAGE_FILE_NAME "antimicrox-${ANTIMICROX_MAJOR_VERSION}.${ANTIMICROX_MINOR_VERSION}.${ANTIMICROX_PATCH_VERSION}") if(WIN32) if(PORTABLE_WIN) set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-PortableWindows") else(PORTABLE_WIN) set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-Windows") endif(PORTABLE_WIN) endif(WIN32) set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}") set(CPACK_PACKAGE_INSTALL_DIRECTORY "AntiMicroX") if(UNIX) set(CPACK_STRIP_FILES "") set(CPACK_SOURCE_STRIP_FILES "") endif() # Building .deb package if(CPACK_GENERATOR STREQUAL "DEB") set(CPACK_DEBIAN_PACKAGE_DEPENDS "qtbase5-dev (>= ${QT_REQUIRED_VERSION}), libsdl2-2.0-0 (>= ${SDL_REQUIRED_VERSION}), libc6") set(CPACK_DEBIAN_PACKAGE_MAINTAINER "pktiuk ") set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "AntiMicroX is a graphical program used to map gamepad buttons to keyboard, mouse, scripts and macros. It is a new fork of discontinued AntiMicro.") message("Preparing documentation for DEB package") add_custom_target(package_docummentation ALL) #Compress changelog and save it as share/doc/xournalpp/changelog.Debian.gz add_custom_command(TARGET package_docummentation PRE_BUILD COMMAND gzip -c -9 -n "${PROJECT_SOURCE_DIR}/CHANGELOG.md" > "changelog.gz" VERBATIM) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/changelog.gz" DESTINATION "share/doc/antimicrox/") #Strip binaries from unnecessary notes, comments, etc add_custom_command(TARGET antimicrox POST_BUILD COMMAND strip --strip-unneeded --remove-section=.comment --remove-section=.note "${CMAKE_CURRENT_BINARY_DIR}/bin/antimicrox" VERBATIM) endif() if(WIN32 AND NOT UNIX) if(NOT PORTABLE_WIN) # We set NSIS as generator for Windows set(CPACK_GENERATOR NSIS) # There is a bug in NSI that does not handle full UNIX paths properly. # Make sure there is at least one set of four backlashes. set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/src/images\\\\antimicrox.ico") set(CPACK_NSIS_MUI_ICON "${CPACK_PACKAGE_ICON}") set(CPACK_NSIS_MUI_UNIICON "${CPACK_PACKAGE_ICON}") set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\antimicrox.exe") set(CPACK_NSIS_DISPLAY_NAME "AntiMicroX") set(CPACK_NSIS_PACKAGE_NAME "AntiMicroX") set(CPACK_NSIS_HELP_LINK "http:\\\\\\\\github.com/AntiMicroX/antimicrox/wiki") set(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\github.com/AntiMicroX/antimicrox") set(CPACK_NSIS_MODIFY_PATH ON) else() set(CPACK_GENERATOR ZIP) endif() endif() set(CPACK_PACKAGE_EXECUTABLES "antimicrox;AntiMicroX") set(CPACK_CREATE_DESKTOP_LINKS "antimicrox") include(CPack) if(WIN32 AND NOT UNIX AND NOT PORTABLE_WIN) configure_file( ${PROJECT_SOURCE_DIR}/cmake/modules/NSIS.definitions.nsh.in ${CMAKE_CURRENT_BINARY_DIR}/assets/nsis/NSIS.definitions.nsh ) endif() ############################### # DOCS ############################### if(BUILD_DOCS) message("Doxygen build enabled") find_package(Doxygen) if (DOXYGEN_FOUND) # set input and output files set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/other/Doxyfile_config.in) set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile) # request to configure the file configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY) # note the option ALL which allows to build the docs together with the application add_custom_target( doxygen_docs ALL COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating API documentation with Doxygen" VERBATIM ) else (DOXYGEN_FOUND) message(WARNING "Doxygen need to be installed to generate the doxygen documentation") endif (DOXYGEN_FOUND) endif(BUILD_DOCS) AntiMicroX-antimicrox-b300273/CONTRIBUTING.md000066400000000000000000000032071471077622000204050ustar00rootroot00000000000000# Contributing to AntiMicroX We welcome and appreciate all contributions to this open source project! ## How to contribute Before contributing, please take a moment to review the following guidelines: 1. Check the [issue tracker](https://github.com/AntiMicroX/antimicrox/issues) to see if the issue or feature you're interested in has already been reported or discussed. 2. If you would like to suggest a new feature, please [start a new issue](https://github.com/AntiMicroX/antimicrox/issues/new/choose) to discuss the proposal. 3. If you would like to contribute code, check the [project's coding guidelines](https://github.com/AntiMicroX/antimicrox/wiki/Coding-guidelines) and make sure your code is well-documented preferably in doxygen-compatible format. 4. Submit a pull request to the main repository for review. In case of preparing bigger changes into the codebase it is recommended to firstly open `Draft Pull Request` to show what you are going to do. During coding you may find [AntiMicroX online docs](https://antimicrox.github.io/doxygen/) useful. ## Translation Translation process is handled via [Weblate](https://weblate.org/). If you want to help just click this [link](https://hosted.weblate.org/engage/antimicrox). Translation status Translation status More information about translating can be found [here](https://github.com/AntiMicroX/antimicrox/wiki/Translating-AntiMicroX). ## License By contributing to this project, you agree to license your contributions under the GPL-3.0 license. AntiMicroX-antimicrox-b300273/LICENSE000066400000000000000000001045151471077622000171650ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . AntiMicroX-antimicrox-b300273/ProfileTips.md000066400000000000000000000077721471077622000207510ustar00rootroot00000000000000Profile Tips ============ ## Sticks ### Dead Zones The XInput standard of 8,000 will typically be used in profiles for analog sticks. For an Xbox 360 controller, that value tends to be the best minimum value to ensure that no unintentional events are produced due to what position a stick will be centered at. When using a different controller, you will likely want to play with the value of the dead zone used for the analog sticks and find what works best for your controller. As an example, when I make profiles for my Logitech F310 gamepad, I find that using a dead zone value of 2,000 for the analog sticks works best. ### Left Stick (Keyboard) The default diagonal range of 45 degrees is recommended when mapping keyboard keys to an analog stick when using the **standard** stick mode. If only one action should ever occur at a time and the diagonal direction doesn't matter as much, you might want to look into **4-way cardinal** stick mode. That can be useful for navigating menus or mapping weapon hotkeys to an analog stick. Some games will overreact when mapping WASD or other keyboard keys to an analog stick. This is mainly due to how quickly directions can be changed especially if you have the stick positioned right around where a diagonal zone resides. If you encounter problems in game or you just want to make movement a little more definitive, you can adjust the **stick delay** value used for that stick. That will cause direction changes to be slightly delayed. Even setting the value to 0.01 seconds can greatly increase control in some games. ### Right Stick (Mouse) To allow for better mouse control with an analog stick, it is recommended that you use a diagonal range of at least 65 degrees instead of the normal 45 degree value. If you want more twitchy mouse control, you will likely want to set the diagonal range of the stick to 89 degrees or 90 degrees. This will minimize the range used for the absolute cardinal directions. Another tip that will allow for more twitchy mouse control is related to the dead zone used for the analog stick. Decreasing the value used for the stick dead zone can help make mouse control feel more responsive than when using the standard value of 8,000 even when using an Xbox 360 controller. Based on my experience, even decreasing the value to 6,000 can make a huge difference. The big compromise is that there might be some mouse cursor drift if the analog stick does not center back to the assigned dead zone. On my Xbox 360 controller, I find that the stick can get stuck slightly in the southwest region of the stick; the other directions don't have this issue. However, the mouse cursor drift is very minimal and you can easily compensate while playing a game. It doesn't hinder gameplay and the benefit obtained far outweights the minor problem. One final thing that you can do to make mouse movement more twitchy is to enable extra acceleration for mouse events. Changing the **extra duration** of acceleration will have the biggest impact on mouse movement. Increasing the maximum extra duration of the acceleration will loosen the mouse movement. Changing the **multiplier** is another option that will change how mouse movement behaves. One final option that can be changed is to use a different curve for extra acceleration. **Linear** is still the default setting since it was the only option available for many versions but I find myself using **Ease Out Quad** lately. Besides altering the final multiplier used, it also changes the final duration experienced. With all the options available for extra acceleration, you will have an easier time performing a quick 180 degree turn while still having precision on the low end of a stick for aiming at targets. ## Action Names It is generally recommended that you specify action names when making profiles that you will share with other people. This will allow other people to more easily decipher what buttons are used for in a profile. Specifying action names can also be a helpful reminder for yourself in order to document a more complex action. AntiMicroX-antimicrox-b300273/README.md000066400000000000000000000161231471077622000174340ustar00rootroot00000000000000# Icon AntiMicroX 1. [Description](#description) 2. [License](#license) 3. [Installation](#installation) 4. [Wiki](#wiki) 5. [Command Line](#command-line) 6. [Testing Under Linux](#testing-under-linux) 7. [AntiMicroX Profiles](#antimicrox-profiles) 8. [Support](#support) ## Description AntiMicroX is a graphical program used to map gamepad keys to keyboard, mouse, scripts and macros. You can use this program to control any desktop application with a gamepad on Linux🐧 and Windows 🪟. It can be also used for generating SDL2 configuration (useful for mapping atypical gamepads to generic ones like xbox360). We support X.org and Wayland. Features: - Mapping of gamepads/joystick buttons to: - keyboard buttons - mouse buttons and moves - scripts and executables - macros consisting of elements mentioned above - Assigning multiple switchable sets of mappings to gamepad. - Auto profiles - assign profile to active application window (not in Wayland [note](https://github.com/AntiMicroX/antimicrox/issues/303)). This program is currently supported under various Linux distributions. This application is continuation of project called `AntiMicro`, which was later abandoned and revived by juliagoda. Legacy repositories: - First AntiMicroX repository: https://github.com/juliagoda/antimicroX - Second, maintained by organization: https://github.com/AntiMicro/antimicro - First, original AntiMicro repository: https://github.com/Ryochan7/antimicro **Screenshots:** Disclaimer: Theme may depend on your system configuration.
Main Window Mapping
Calibration Advanced settings
## License This program is licensed under the GPL v.3. Please read the LICENSE text document included with the source code if you would like to read the terms of the license. The license can also be found online at http://www.gnu.org/licenses/gpl.txt ## Installation ### Windows Just download `antimicrox-X.X.X-AMD64.exe` from [Release site](https://github.com/AntiMicroX/antimicrox/releases/latest) and install it. ### Flatpak The flatpak version is distributed on Flathub, and runs on most major Linux distributions. See instructions here: [Flathub application page](https://flathub.org/apps/details/io.github.antimicrox.antimicrox) If you have Flathub [set up](https://flatpak.org/setup/) already: ```bash flatpak install flathub io.github.antimicrox.antimicrox ``` ❕ Flatpak package may not work correctly with wayland [(Fix available here)](https://github.com/AntiMicroX/antimicrox/wiki/Open-uinput-error) ### AppImage Download from the [release site](https://github.com/AntiMicroX/antimicrox/releases). It is recommended to use [AppImageLauncher](https://github.com/TheAssassin/AppImageLauncher) with this package. ### Debian/Ubuntu-based distributions Download from the [release site](https://github.com/AntiMicroX/antimicrox/releases) and install `.deb` package. ### Fedora ``` dnf install antimicrox ``` ### openSUSE A [package](https://software.opensuse.org/package/antimicrox) is available. ``` zypper install antimicrox ``` ### Arch Linux or Arch Linux based distributions: ``` trizen -S antimicrox ``` **or** pre-built version can de downloaded from unofficial repository called [chaotic-aur](https://lonewolf.pedrohlc.com/chaotic-aur/). Append (one of listed mirrors) to `/etc/pacman.conf`: ```bash # Brazil Server = http://lonewolf-builder.duckdns.org/$repo/$arch # Germany Server = http://chaotic.bangl.de/$repo/$arch # USA (Cloudflare cached) Server = https://repo.kitsuna.net/$arch # Netherlands Server = https://chaotic.tn.dedyn.io/$arch ``` To check signature, add keys: ```bash sudo pacman-key --keyserver hkp://keyserver.ubuntu.com -r 3056513887B78AEB 8A9E14A07010F7E3 sudo pacman-key --lsign-key 3056513887B78AEB sudo pacman-key --lsign-key 8A9E14A07010F7E3 ``` Install package ```bash pacman -S antimicrox ``` ### Building Yourself List of required dependencies and build instructions can be found [here](./BUILDING.md). ### Packages status Status of package `antimicrox`: [![Packaging status](https://repology.org/badge/vertical-allrepos/antimicrox.svg?columns=3&minversion=3.1)](https://repology.org/project/antimicrox/versions) ## Command Line Run `antimicrox --help` or read `man antimicrox` for command-line parameters.
Commandline for flatpak In case of flatpak package AntiMicroX can be launched with command:
flatpak run io.github.antimicrox.antimicrox instead of just antimicrox
In some cases it may be good to add alias
alias antimicrox='flatpak run io.github.antimicrox.antimicrox'
fo file ~/.bashrc
## Wiki [Look here](https://github.com/AntiMicroX/antimicrox/wiki) ## Testing Under Linux If you are having problems with antimicrox detecting a controller or detecting all axes and buttons, you should test the controller outside of antimicrox to check if the problem is with antimicrox or not. The two endorsed programs for testing gamepads outside of antimicrox are **sdl-jstest** (**sdl2-jstest**) and **evtest**. SDL2 utilizes evdev on Linux so performing testing with older programs that use joydev won't be as helpful since some devices behave a bit differently between the two systems. Another method also exists, which can be found [here](https://github.com/juliagoda/SDL_JoystickButtonNames). ## AntiMicroX Profiles If you would like to send the profile you are using for your application or find something for yourself, [here](https://github.com/AntiMicroX/antimicrox-profiles) is the forked repository. If you want to report a bug, ask a question or share a suggestion, you can do that on the antimicrox page or on the [antimicrox-profiles](https://github.com/AntiMicroX/antimicrox-profiles) page. ## Support There are several ways to get help with AntiMicroX. The easiest way is to upvote (with 👍) issues you thing are the most important ones. It is also possible to fund some issues using [Polar](https://polar.sh) platform to attract contributors. ### Contributing Any contributions into codebase are welcome. You can find contribution guide [here](./CONTRIBUTING.md). Some issues are may have bounties which are meant to attract contributors. ### Translation Translation process is handled via [Weblate](https://weblate.org/). If you want to help just click this [link](https://hosted.weblate.org/engage/antimicrox). Translation status Translation status More information about translating can be found [here](https://github.com/AntiMicroX/antimicrox/wiki/Translating-AntiMicroX). AntiMicroX-antimicrox-b300273/cmake/000077500000000000000000000000001471077622000172325ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/cmake/modules/000077500000000000000000000000001471077622000207025ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/cmake/modules/FindSDL2.cmake000066400000000000000000000334421471077622000232170ustar00rootroot00000000000000# https://github.com/aminosbh/sdl2-cmake-modules/blob/master/FindSDL2.cmake # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. # Copyright 2019 Amine Ben Hassouna # Copyright 2000-2019 Kitware, Inc. and Contributors # All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of Kitware, Inc. nor the names of Contributors # may be used to endorse or promote products derived from this # software without specific prior written permission. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #[=======================================================================[.rst: FindSDL2 -------- Locate SDL2 library This module defines the following 'IMPORTED' targets: :: SDL2::Core The SDL2 library, if found. Libraries should link to SDL2::Core SDL2::Main The SDL2main library, if found. Applications should link to SDL2::Main instead of SDL2::Core This module will set the following variables in your project: :: SDL2_LIBRARIES, the name of the library to link against SDL2_INCLUDE_DIRS, where to find SDL.h SDL2_FOUND, if false, do not try to link to SDL2 SDL2MAIN_FOUND, if false, do not try to link to SDL2main SDL2_VERSION_STRING, human-readable string containing the version of SDL2 This module responds to the following cache variables: :: SDL2_PATH Set a custom SDL2 Library path (default: empty) SDL2_NO_DEFAULT_PATH Disable search SDL2 Library in default path. If SDL2_PATH (default: ON) Else (default: OFF) SDL2_INCLUDE_DIR SDL2 headers path. SDL2_LIBRARY SDL2 Library (.dll, .so, .a, etc) path. SDL2MAIN_LIBRAY SDL2main Library (.a) path. SDL2_BUILDING_LIBRARY This flag is useful only when linking to SDL2_LIBRARIES insead of SDL2::Main. It is required only when building a library that links to SDL2_LIBRARIES, because only applications need main() (No need to also link to SDL2main). If this flag is defined, then no SDL2main will be added to SDL2_LIBRARIES and no SDL2::Main target will be created. Don't forget to include SDLmain.h and SDLmain.m in your project for the OS X framework based version. (Other versions link to -lSDL2main which this module will try to find on your behalf.) Also for OS X, this module will automatically add the -framework Cocoa on your behalf. Additional Note: If you see an empty SDL2_LIBRARY in your project configuration, it means CMake did not find your SDL2 library (SDL2.dll, libsdl2.so, SDL2.framework, etc). Set SDL2_LIBRARY to point to your SDL2 library, and configure again. Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value as appropriate. These values are used to generate the final SDL2_LIBRARIES variable and the SDL2::Core and SDL2::Main targets, but when these values are unset, SDL2_LIBRARIES, SDL2::Core and SDL2::Main does not get created. $SDL2DIR is an environment variable that would correspond to the ./configure --prefix=$SDL2DIR used in building SDL2. l.e.galup 9-20-02 Created by Amine Ben Hassouna: Adapt FindSDL.cmake to SDL2 (FindSDL2.cmake). Add cache variables for more flexibility: SDL2_PATH, SDL2_NO_DEFAULT_PATH (for details, see doc above). Mark 'Threads' as a required dependency for non-OSX systems. Modernize the FindSDL2.cmake module by creating specific targets: SDL2::Core and SDL2::Main (for details, see doc above). Original FindSDL.cmake module: Modified by Eric Wing. Added code to assist with automated building by using environmental variables and providing a more controlled/consistent search behavior. Added new modifications to recognize OS X frameworks and additional Unix paths (FreeBSD, etc). Also corrected the header search path to follow "proper" SDL guidelines. Added a search for SDLmain which is needed by some platforms. Added a search for threads which is needed by some platforms. Added needed compile switches for MinGW. On OSX, this will prefer the Framework version (if found) over others. People will have to manually change the cache value of SDL2_LIBRARY to override this selection or set the SDL2_PATH variable or the CMake environment CMAKE_INCLUDE_PATH to modify the search paths. Note that the header path has changed from SDL/SDL.h to just SDL.h This needed to change because "proper" SDL convention is #include "SDL.h", not . This is done for portability reasons because not all systems place things in SDL/ (see FreeBSD). #]=======================================================================] # Define options for searching SDL2 Library in a custom path set(SDL2_PATH "" CACHE STRING "Custom SDL2 Library path") set(_SDL2_NO_DEFAULT_PATH OFF) if(SDL2_PATH) set(_SDL2_NO_DEFAULT_PATH ON) endif() set(SDL2_NO_DEFAULT_PATH ${_SDL2_NO_DEFAULT_PATH} CACHE BOOL "Disable search SDL2 Library in default path") unset(_SDL2_NO_DEFAULT_PATH) set(SDL2_NO_DEFAULT_PATH_CMD) if(SDL2_NO_DEFAULT_PATH) set(SDL2_NO_DEFAULT_PATH_CMD NO_DEFAULT_PATH) endif() # Search for the SDL2 include directory # Modified to SDL2/SDL.h for antimicroX find_path(SDL2_INCLUDE_DIR SDL2/SDL.h HINTS ENV SDL2DIR ${SDL2_NO_DEFAULT_PATH_CMD} PATH_SUFFIXES SDL2 # path suffixes to search inside ENV{SDL2DIR} include/SDL2 include PATHS ${SDL2_PATH} DOC "Where the SDL2 headers can be found" ) set(SDL2_INCLUDE_DIRS "${SDL2_INCLUDE_DIR}") if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(VC_LIB_PATH_SUFFIX lib/x64) else() set(VC_LIB_PATH_SUFFIX lib/x86) endif() # SDL-2.0 is the name used by FreeBSD ports... # don't confuse it for the version number. find_library(SDL2_LIBRARY NAMES SDL2 SDL-2.0 HINTS ENV SDL2DIR ${SDL2_NO_DEFAULT_PATH_CMD} PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX} PATHS ${SDL2_PATH} DOC "Where the SDL2 Library can be found" ) set(SDL2_LIBRARIES "${SDL2_LIBRARY}") if(NOT SDL2_BUILDING_LIBRARY) if(NOT SDL2_INCLUDE_DIR MATCHES ".framework") # Non-OS X framework versions expect you to also dynamically link to # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms # seem to provide SDL2main for compatibility even though they don't # necessarily need it. if(SDL2_PATH) set(SDL2MAIN_LIBRARY_PATHS "${SDL2_PATH}") endif() if(NOT SDL2_NO_DEFAULT_PATH) set(SDL2MAIN_LIBRARY_PATHS /sw /opt/local /opt/csw /opt "${SDL2MAIN_LIBRARY_PATHS}" ) endif() find_library(SDL2MAIN_LIBRARY NAMES SDL2main HINTS ENV SDL2DIR ${SDL2_NO_DEFAULT_PATH_CMD} PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX} PATHS ${SDL2MAIN_LIBRARY_PATHS} DOC "Where the SDL2main library can be found" ) unset(SDL2MAIN_LIBRARY_PATHS) endif() endif() # SDL2 may require threads on your system. # The Apple build may not need an explicit flag because one of the # frameworks may already provide it. # But for non-OSX systems, I will use the CMake Threads package. if(NOT APPLE) find_package(Threads QUIET) if(NOT Threads_FOUND) set(SDL2_THREADS_NOT_FOUND "Could NOT find Threads (Threads is required by SDL2).") if(SDL2_FIND_REQUIRED) message(FATAL_ERROR ${SDL2_THREADS_NOT_FOUND}) else() if(NOT SDL2_FIND_QUIETLY) message(STATUS ${SDL2_THREADS_NOT_FOUND}) endif() return() endif() unset(SDL2_THREADS_NOT_FOUND) endif() endif() # MinGW needs an additional link flag, -mwindows # It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -mwindows if(MINGW) set(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "link flags for MinGW") endif() if(SDL2_LIBRARY) # For SDL2main if(SDL2MAIN_LIBRARY AND NOT SDL2_BUILDING_LIBRARY) list(FIND SDL2_LIBRARIES "${SDL2MAIN_LIBRARY}" _SDL2_MAIN_INDEX) if(_SDL2_MAIN_INDEX EQUAL -1) set(SDL2_LIBRARIES "${SDL2MAIN_LIBRARY}" ${SDL2_LIBRARIES}) endif() unset(_SDL2_MAIN_INDEX) endif() # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. # CMake doesn't display the -framework Cocoa string in the UI even # though it actually is there if I modify a pre-used variable. # I think it has something to do with the CACHE STRING. # So I use a temporary variable until the end so I can set the # "real" variable in one-shot. if(APPLE) set(SDL2_LIBRARIES ${SDL2_LIBRARIES} -framework Cocoa) endif() # For threads, as mentioned Apple doesn't need this. # In fact, there seems to be a problem if I used the Threads package # and try using this line, so I'm just skipping it entirely for OS X. if(NOT APPLE) set(SDL2_LIBRARIES ${SDL2_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) endif() # For MinGW library if(MINGW) set(SDL2_LIBRARIES ${MINGW32_LIBRARY} ${SDL2_LIBRARIES}) endif() endif() # Read SDL2 version if(SDL2_INCLUDE_DIR AND EXISTS "${SDL2_INCLUDE_DIR}/SDL_version.h") file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$") file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$") file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$") string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MAJOR "${SDL2_VERSION_MAJOR_LINE}") string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MINOR "${SDL2_VERSION_MINOR_LINE}") string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_PATCH "${SDL2_VERSION_PATCH_LINE}") set(SDL2_VERSION_STRING ${SDL2_VERSION_MAJOR}.${SDL2_VERSION_MINOR}.${SDL2_VERSION_PATCH}) unset(SDL2_VERSION_MAJOR_LINE) unset(SDL2_VERSION_MINOR_LINE) unset(SDL2_VERSION_PATCH_LINE) unset(SDL2_VERSION_MAJOR) unset(SDL2_VERSION_MINOR) unset(SDL2_VERSION_PATCH) endif() include(FindPackageHandleStandardArgs) set(SDL2_REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) if(SDL2MAIN_LIBRARY) list(APPEND SDL2_REQUIRED_VARS SDL2MAIN_LIBRARY SDL2_INCLUDE_DIR) endif() find_package_handle_standard_args(SDL2 REQUIRED_VARS ${SDL2_REQUIRED_VARS} VERSION_VAR SDL2_VERSION_STRING) mark_as_advanced(SDL2_PATH SDL2_NO_DEFAULT_PATH SDL2_LIBRARY SDL2MAIN_LIBRARY SDL2_INCLUDE_DIR SDL2_BUILDING_LIBRARY) # SDL2:: targets (SDL2::Core and SDL2::Main) if(SDL2_FOUND) # SDL2::Core target if(SDL2_LIBRARY AND NOT TARGET SDL2::Core) add_library(SDL2::Core UNKNOWN IMPORTED) set_target_properties(SDL2::Core PROPERTIES IMPORTED_LOCATION "${SDL2_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}") if(APPLE) # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. # For more details, please see above. set_property(TARGET SDL2::Core APPEND PROPERTY INTERFACE_LINK_OPTIONS -framework Cocoa) else() # For threads, as mentioned Apple doesn't need this. # For more details, please see above. set_property(TARGET SDL2::Core APPEND PROPERTY INTERFACE_LINK_LIBRARIES Threads::Threads) endif() endif() # SDL2::Main target # Applications should link to SDL2::Main instead of SDL2::Core # For more details, please see above. if(NOT SDL2_BUILDING_LIBRARY AND NOT TARGET SDL2::Main) if(SDL2_INCLUDE_DIR MATCHES ".framework" OR NOT SDL2MAIN_LIBRARY) add_library(SDL2::Main INTERFACE IMPORTED) set_property(TARGET SDL2::Main PROPERTY INTERFACE_LINK_LIBRARIES SDL2::Core) elseif(SDL2MAIN_LIBRARY) # MinGW requires that the mingw32 library is specified before the # libSDL2main.a static library when linking. # The SDL2::MainInternal target is used internally to make sure that # CMake respects this condition. add_library(SDL2::MainInternal UNKNOWN IMPORTED) set_property(TARGET SDL2::MainInternal PROPERTY IMPORTED_LOCATION "${SDL2MAIN_LIBRARY}") set_property(TARGET SDL2::MainInternal PROPERTY INTERFACE_LINK_LIBRARIES SDL2::Core) add_library(SDL2::Main INTERFACE IMPORTED) if(MINGW) # MinGW needs an additional link flag '-mwindows' and link to mingw32 set_property(TARGET SDL2::Main PROPERTY INTERFACE_LINK_LIBRARIES "mingw32" "-mwindows") endif() set_property(TARGET SDL2::Main APPEND PROPERTY INTERFACE_LINK_LIBRARIES SDL2::MainInternal) endif() endif() endif() AntiMicroX-antimicrox-b300273/cmake/modules/NSIS.definitions.nsh.in000066400000000000000000000011251471077622000251060ustar00rootroot00000000000000!define VERSION "@APP_VERSION@" !define APP_VERSION "@APP_VERSION@" !define APP_NAME "@APP_NAME@" !define EXE_NAME "@EXE_NAME@" !define README_FILE "README" !define LICENSE_FILE "@PROJECT_SOURCE_DIR@resourcestextLICENSE" !define MUI_ICON "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@.ico" !define MUI_UNICON "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@.ico" !define MUI_WELCOMEFINISHPAGE_BITMAP "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@-banner.bmp" !define MUI_UNWELCOMEFINISHPAGE_BITMAP "@PROJECT_SOURCE_DIR@resourcesgraphics@APP_LOW_NAME@-banner.bmp" !define PATCH "0"AntiMicroX-antimicrox-b300273/cmake_uninstall.cmake.in000066400000000000000000000020131471077622000227260ustar00rootroot00000000000000if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") exec_program( "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") endif(NOT "${rm_retval}" STREQUAL 0) else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") message(STATUS "File $ENV{DESTDIR}${file} does not exist.") endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") endforeach(file) AntiMicroX-antimicrox-b300273/other/000077500000000000000000000000001471077622000172735ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/other/60-antimicrox-uinput.rules000066400000000000000000000002201471077622000242630ustar00rootroot00000000000000#Enable user access to keyboard using uinput event generator SUBSYSTEM=="misc", KERNEL=="uinput", OPTIONS+="static_node=uinput", TAG+="uaccess" AntiMicroX-antimicrox-b300273/other/CMakeLists.txt000066400000000000000000000005031471077622000220310ustar00rootroot00000000000000add_subdirectory(appdata) add_custom_target(manpage) add_custom_command(TARGET manpage PRE_BUILD COMMAND gzip -c -9 -n "${PROJECT_SOURCE_DIR}/other/antimicrox.1" > "antimicrox.1.gz" VERBATIM ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/antimicrox.1.gz" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/man/man1") AntiMicroX-antimicrox-b300273/other/Doxyfile_config.in000066400000000000000000000024071471077622000227360ustar00rootroot00000000000000PROJECT_NAME = "AntiMicroX" OUTPUT_DIRECTORY = @CMAKE_CURRENT_SOURCE_DIR@/docs/ INPUT = @CMAKE_CURRENT_SOURCE_DIR@/src/ RECURSIVE = YES QT_AUTOBRIEF = YES OPTIMIZE_OUTPUT_FOR_C = YES PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/share/icons/application/48x48/apps/48-apps-io.github.antimicrox.antimicrox.png HAVE_DOT = YES DOT_IMAGE_FORMAT = svg INTERACTIVE_SVG = YES EXTRACT_ALL = YES EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES # If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for # each documented class showing the direct and indirect inheritance relations. # Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES COLLABORATION_GRAPH = YES # If the UML_LOOK tag is set to YES, doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. UML_LOOK = NO CALL_GRAPH = YES CALLER_GRAPH = YES GRAPHICAL_HIERARCHY = YES AntiMicroX-antimicrox-b300273/other/antimicrox.1000066400000000000000000000043211471077622000215320ustar00rootroot00000000000000.\" Manpage for antimicrox. .\" Contact juliagoda.pl@protonmail.com to correct errors or typos. .TH ANTIMICROX "1" "7 January 2020" "antimicrox 2.25" "User Commands" .SH NAME AntiMicroX \- map keyboard keys and mouse controls to a gamepad .SH SYNOPSIS .B antimicrox [\fIOPTION\fR] [\fIPROFILE\fR] .SH DESCRIPTION .PP AntiMicroX is a graphical program used to map gamepad buttons to keyboard, mouse, scripts and macros. However, you can use this program to control any desktop application with a gamepad. .TP \fB\-\-tray\fR launch program in system tray only .TP \fB\-\-no\-tray\fR launch program with the tray menu disabled .TP \fB\-h\fR, \fB\-\-help\fR display this help and exit .TP \fB\-v\fR, \fB\-\-version\fR output version information and exit .TP \fB\-\-profile\fR \fI\fR use specified profile as default for selected controllers. Defaults to all controllers. .TP \fB\-\-profile\-controller\fR \fI\fR apply configuration file to a specific controller. can be an controller index, name, or GUID. .TP \fB\-\-hidden\fR launch program without the main window .TP \fB\-\-unload\fR \fI[]\fR unload currently enabled profile(s). Value can be a controller index, name, or GUID. .TP \fB\-\-startSet\fR \fI\fR \fI[]\fR start joysticks on a specific set. Value can be a controller index, name, or GUID. .TP \fB\-\-next\fR Advance profile loading set options. .TP \fB\-\-log\-level\fR \fI{debug,info,warn}\fR Enable logging. Default: warn .TP \fB\-l\fR, \fB\-\-list\fR Print information about joysticks detected by SDL. .TP \fB\-\-map\fR \fI\fR Open game controller mapping window of selected controller. Value can be a controller index or GUID. .TP \fB\-\-eventgen\fR \fI{xtest,uinput}\fR Choose between using XTest support and uinput support for event generation. Default: xtest. .SH BUGS See https://github.com/AntiMicroX/antimicrox/issues .SH AUTHOR Paweł Kotiuk (kotiuk@zohomail.eu) Jagoda Górska (juliagoda.pl@protonmail.com) Jeff Backus (jeff@jsbackus.com) Travis Nickles (nickles.travis@gmail.com) and other contributors: https://github.com/AntiMicroX/antimicrox/graphs/contributors .SH "REPORTING BUGS" Report dir bugs to antimicrox issues page: https://github.com/AntiMicroX/antimicrox/issues AntiMicroX-antimicrox-b300273/other/appdata/000077500000000000000000000000001471077622000207055ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/other/appdata/CMakeLists.txt000066400000000000000000000015771471077622000234570ustar00rootroot00000000000000# Make appdata optional when installing an application. if(APPDATA) add_custom_target(appdata) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/PO_files/") add_custom_command(TARGET appdata PRE_BUILD # Add an entry per language COMMAND msgfmt "${PROJECT_SOURCE_DIR}/other/appdata/PO_files/en.po" -o "${CMAKE_CURRENT_BINARY_DIR}/PO_files/en.mo" COMMAND itstool -i "${PROJECT_SOURCE_DIR}/other/appdata/appdata.its" -j "${PROJECT_SOURCE_DIR}/other/appdata/io.github.antimicrox.antimicrox.appdata.xml.in" -o "io.github.antimicrox.antimicrox.appdata.xml" "${CMAKE_CURRENT_BINARY_DIR}/PO_files/*.mo" ) # Only install an appdata file ifthe user requested to have one built. install(FILES "${CMAKE_CURRENT_BINARY_DIR}/io.github.antimicrox.antimicrox.appdata.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo") endif(APPDATA) AntiMicroX-antimicrox-b300273/other/appdata/PO_files/000077500000000000000000000000001471077622000224055ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/other/appdata/PO_files/en.po000066400000000000000000000064031471077622000233520ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2020-09-27 17:28+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. (itstool) path: component/name #: io.github.antimicrox.antimicrox.appdata.xml.in:6 msgid "AntiMicroX" msgstr "" #. (itstool) path: component/summary #: io.github.antimicrox.antimicrox.appdata.xml.in:7 msgid "Graphical program used to map gamepad buttons to keyboard, mouse, scripts and macros." msgstr "" #. (itstool) path: description/p #: io.github.antimicrox.antimicrox.appdata.xml.in:9 msgid "AntiMicroX is a graphical program used to map gamepad buttons/joysticks to keyboard, mouse, scripts and macros. It can be also used for generating SLD2 configuration (useful for mapping atypical gamepads to generic ones like xbox360)." msgstr "" #. (itstool) path: ul/li #: io.github.antimicrox.antimicrox.appdata.xml.in:18 msgid "keyboard buttons" msgstr "" #. (itstool) path: ul/li #: io.github.antimicrox.antimicrox.appdata.xml.in:19 msgid "mouse buttons and moves" msgstr "" #. (itstool) path: ul/li #: io.github.antimicrox.antimicrox.appdata.xml.in:20 msgid "scripts and launching apps" msgstr "" #. (itstool) path: ul/li #: io.github.antimicrox.antimicrox.appdata.xml.in:21 msgid "macros consisting of elements mentioned above" msgstr "" #. (itstool) path: description/p #: io.github.antimicrox.antimicrox.appdata.xml.in:15 msgid "It allows mapping of gamepads/joystick buttons to: <_:ul-1/>" msgstr "" #. (itstool) path: description/p #: io.github.antimicrox.antimicrox.appdata.xml.in:24 msgid "AntiMicroX was inspired by QJoyPad." msgstr "" #. (itstool) path: screenshot/caption #: io.github.antimicrox.antimicrox.appdata.xml.in:48 msgid "Main Window (Light Theme)" msgstr "" #. (itstool) path: screenshot/caption #: io.github.antimicrox.antimicrox.appdata.xml.in:52 msgid "Main Window (Dark Theme)" msgstr "" #. (itstool) path: screenshot/caption #: io.github.antimicrox.antimicrox.appdata.xml.in:56 msgid "Controller Calibration (Dark Theme)" msgstr "" #. (itstool) path: screenshot/caption #: io.github.antimicrox.antimicrox.appdata.xml.in:60 msgid "Controller Mapping (Dark Theme)" msgstr "" #. (itstool) path: screenshot/caption #: io.github.antimicrox.antimicrox.appdata.xml.in:64 msgid "Advanced Settings (Dark Theme)" msgstr "" #. (itstool) path: screenshot/caption #: io.github.antimicrox.antimicrox.appdata.xml.in:68 msgid "About Window (Dark Theme)" msgstr "" #. (itstool) path: keywords/keyword #: io.github.antimicrox.antimicrox.appdata.xml.in:73 msgid "game" msgstr "" #. (itstool) path: keywords/keyword #: io.github.antimicrox.antimicrox.appdata.xml.in:74 msgid "controller" msgstr "" #. (itstool) path: keywords/keyword #: io.github.antimicrox.antimicrox.appdata.xml.in:75 msgid "joystick" msgstr "" #. (itstool) path: keywords/keyword #: io.github.antimicrox.antimicrox.appdata.xml.in:76 msgid "keyboard" msgstr "" #. (itstool) path: keywords/keyword #: io.github.antimicrox.antimicrox.appdata.xml.in:77 msgid "mouse" msgstr "" #. (itstool) path: categories/category #: io.github.antimicrox.antimicrox.appdata.xml.in:80 msgid "Utility" msgstr "" AntiMicroX-antimicrox-b300273/other/appdata/appdata.its000066400000000000000000000007651471077622000230500ustar00rootroot00000000000000 AntiMicroX-antimicrox-b300273/other/appdata/io.github.antimicrox.antimicrox.appdata.xml.in000066400000000000000000000122671471077622000316750ustar00rootroot00000000000000 io.github.antimicrox.antimicrox AntiMicroX Graphical program used to map gamepad buttons to keyboard, mouse, scripts and macros pktiuk CC0-1.0 GPL-3.0-or-later

AntiMicroX is a graphical program used to map gamepad buttons/joysticks to keyboard, mouse, scripts and macros. It can be also used for generating SLD2 configuration (useful for mapping atypical gamepads to generic ones like xbox360).

Features:

  • Mapping of gamepads/joystick buttons to: ⌨️keyboard buttons, 🖱️mouse buttons and moves, scripts, executables and macros consisting of elements mentioned here
  • Assigning multiple switchable sets of mappings to gamepad.
  • Auto profiles - assign profile to active application window.

AntiMicroX was inspired by QJoyPad.

Main Window (Light Theme) https://raw.githubusercontent.com/AntiMicroX/antimicrox/master/other/appdata/screenshots/app_light.png Main Window (Dark Theme) https://raw.githubusercontent.com/AntiMicroX/antimicrox/master/other/appdata/screenshots/app_dark.png Controller Calibration (Dark Theme) https://raw.githubusercontent.com/AntiMicroX/antimicrox/master/other/appdata/screenshots/calibration.png Controller Mapping (Dark Theme) https://raw.githubusercontent.com/AntiMicroX/antimicrox/master/other/appdata/screenshots/controllermapping.png Advanced Settings (Dark Theme) https://raw.githubusercontent.com/AntiMicroX/antimicrox/master/other/appdata/screenshots/advanced.png About Window (Dark Theme) https://raw.githubusercontent.com/AntiMicroX/antimicrox/master/other/appdata/screenshots/about.png https://github.com/AntiMicroX/antimicrox/ https://github.com/AntiMicroX/antimicrox/issues Utility Qt gamepad io.github.antimicrox.antimicrox.desktop antimicrox application/x-amgp game gamepad controller joystick keyboard mouse mapping
AntiMicroX-antimicrox-b300273/other/appdata/screenshots/000077500000000000000000000000001471077622000232455ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/other/appdata/screenshots/about.png000066400000000000000000001057171471077622000251000ustar00rootroot00000000000000PNG  IHDR--QsBIT|dtEXtSoftwaregnome-screenshot> IDATxw`jW.dM14ı8}NwĹ\r_K98K۸n6tcD$y,B~`gosq2 |/x< HuDDDDDDDN'u#[ZZ N &''_KHHz]@.H$r1TWWDMM͏puHfgg=990++kb860xEDDDDDD00 ׋u+++444l-//Qm+ڕwZZZZZH$'xu]l& Ƀq iiiYQlWI=-""""""r&D"$%% ÃmWMʼn7'''B3s4 s-Up9i FS>mPuNi"""""""g0|e lT!0DqU\DDDDDD9a$ES׍9ݲ=6CpF![DDDDDDxצ<Xf5ﻞA3Rqx?fnJm a2'tǕMfNAc51mBH3`M]]\͈,}l>?O_R⃝_pz~I՟k9銛ɺ4xw/O:=g"""}$|/nmsg 5D?5ܬNcký6i]tn|dKp~Iߧ?W>t1KwEDDcq7V%sg) ?]|eK_䟿"3{s.+?Oe/?΃?)iXc?WdW #Z~jRHyoOb?wș.YIw՟u/.1|.[![DD#3,ZCY&a<.LLV<ӫɝec {~-%GyvKů\^Ńl\|/8+{<#]܌ 55 Y%’F?:Ne$ν{h 4z^kWb.l>a2jF5gőA}f~oj-z(NS%ޮriZ oW_aGE|lz' 0w f85js'ms""rVx!Iw]i5h7h". l^^YDDDDDD$>)ǍtңM~~]uC%%%Swq9=\Dc㙆&~,l9+[Wƒd{lM:v_EDDDDDr[7`ݑFlQlQlQ}3^!;--/!""""""2`GUNEDDDDDDbD![DDDDDD$FEDDDDDDbD![DDDDDD$FEDDDDDDbD![DDDDDD$FEDDDDDDbD![DDDDDD$FEDDDDDDbD![DDDDDD$FEDDDDDDbD![DDDDDD$FEDDDDDDbD![DDDDDD$FEDDDDDDbD![DDDDDD$FEDDDDDDbD![DDDDDD$FEDDDDDDb 8%beIcZIWmcG„̈́.N#܂njrB'n91 ٱ7|Fb `xHH"h@S粆N#Vk 1`fs''5w$-uU4U궜a84u%x5}""""""*=}q 架}a$eEapB a""""""0>f0|/lA Fd.)7ݵ}I$94UvGpP ;7X'm9)d,O1n\81-j,YWgMO$‰| xw3 UӍY{DDDDDDU ';l2fc>3ݙ02K4viWiARf'Ø\xvq|nDG!$wn?6Rwu+F^>/gxuw=>?\GxğA\A ׎]""""""ǰ7oXjߩ5L78TYz_0=`Kvp¨Cv\B#Pʝ3D`'Ű3՗im<)dϠQ?(-Ԥn<<؎nYm]"ZWI {5aP]Cv 31 xsEDDDDDbM!DyRDUu]auq]Nݴ ¶COka& 5ڟn?M10\DDDDD\}]töCMckvA{=EXeW'fczԖ?9`c-oE8L h;ֆaO'EDDDDDD5"W^^윾n̙7x:fGm{&c/`PZ2MuC{Jٶu& LjK)Y]鵼_O""""""r6)//?TRR[9>6v 8N`PZ2p6OU%Lv]FcyK]鹜DG!x\}sõ؎-P8u=kc5*d. [g?wvl_DDDz}G^u0^Ou]J+j+c@;p]Lb ԓ>Kcσmg6$ʩED I姷]Lb̏ ڨ5y.8}ebcn ȁ׸'OøƗɗfjX>ޮ$]Wy͞ѼG[TiŘO\vB`׳wq WEDDNBvAʾj3|뉎ˇ]\lD=)˛F TYoRAٺcCծ04kXˋ'ն|Lr!qdKw|.,-9hg,y'M V:iɞtRM8h2r7 `|zǯ㺛>x m.#SެӸZ[frW?`ϖQ Xn7dTx_S3[0K'vNnGjrr H›c|QZuT7k CM$2+Z>~9rZm㻟[D䬓02;ޑ\pdk=EޑYtݵ\wݵ\{,Fvϭ"Y܋wt.'ť97uGh?m\p/^UE%˗5n„-qoVn3dG5⤗9.ߪqHw1# %\ڵ{H}~-ַPၗ:6]2Mǹ"( Ase I۰oV;9$`]{:O%н9$_:\c6<ǡfwI`w y G{O:ztr'fiv)O#0'6dY`~Kl1&&^,p=CqIDDDdSȎ©vh=qBƚ d' '}<_x#:lql0 /-$a~\^J^_RjOW9=l/B.M71̡XpضC@4I<Fp~xOFS0BfMOG rp4 d OFpٓC`6_MUمȍNjzP%_Z4ZǞ$|{?0cfkplksnߺz SgKޡCڷ~ xqW߾@:SYBd5=XO ֫r 1nxp*ѳ#6ۻFqM..ks)F,F,.qAu,۾f{ș>I'r0IxpfL[B\3eW P(ȿkumb~lWmHp}}.#o7nRf\s޽urjxa%l9{Nv/<֩ ܺI>ZOfR߂86-NoAp\i/)PsC4L"t-'e""gk4W\< oC>io,q΅` ƼxMףo9xٷՔO}3- #S{n |vwy$6_w US]ov<`O_ĩSI2y"~b.h_ L$m_ѧWC𱌍.vFJ.g;Xlnyu5[O&uny0$&_b{Lm EnrF c.@T""rPũv(3ȋ4-B{Iؼ(pTgMq>q&߃ѶSh0Lp^i+d3 fZ]3v1ALw>qkVuC֗oG+ziX@0H} ̑#kG4Sw%U.MgL=QSn,}w^]#\%p:b&Ĕi{qD. .ANݛ;3<.3};ܢ5WNӍd/PuNDMEg9vL3O\"F7w=q~6>V<|UʹE_& PDD?(dac4qxf |֑Jr~2]?R?gA{3ޗxb%i/cCoj\/=ݟD;gaD'""V,.Տ>E׭K.xp7?:քe߾w+l\ ̴i|3RCY@{4*fu75]>YW^G\ya'N\bܕir}˜ [l?,\>ɧR30=Ӄax)dMI\ZaӦhI?Ks|QC>17(u};A`urOt_btSy+! s^ծ;oqlƆVL}[l#i\ݣ6DZl`$DsMv I'SkcG"'D<} l$ 5Rw#K/͒.I^߾^ZpKVox2/2_bhuW+;A0;&iypx.{-#""""""S=e;p-[ĭ&Ք> 1?R*dc?NdwfU};r \shqe"""""""nvWŮDǩEbO(G[NDDDDDD:Qn9@#]Ũ5 Zh='[3 n8u'8C 0;Lx9tzqL;-9)dwî8eC66akNpЁM^^ u}'\DDDDDDz I-?L$ڱc 憨}$Bvw ' vƉp]@cmTKȩ=."""""rRAt Z:DpJ "."""""rw2jJCmtA![DD&\ɵky:Ls5(ƒڎuM|+><SEDD8 """y/kmOt%ur%yCk7YDDD-""c^z- Zhs:\}3[p=HBȀ`3*fH'cX!L"a_:d'"""P(|TL UvȉP,O1|<}\~m"""2il P]~[^c;뒸C![DDZ\ nK#.XC|\!htm\DD_Yܯ7SR^CFޔY\߽BI'=e|K=EDDC;|\f7q,γ|,-ͪpu=95; ,QYw0;;;#""""""2*))lQlQlQlQlQlQlE7njEDDDDDDbf1OB6@AAA_U-""""""rJ^ulQlQlQlQlw$đL9dærr69cadﲳfĄ|WeʦnHG:Y(`\(۴w?>*;99=Us൧bwF_gH`M``>qW\XЄFJ6-e;h׭sֱvA#?x}`\+c5Ry/={MsJ(6m- x[Q׾F0&0i[򶻓QXg̰t|-TMNAնw^aQ&-.H=RѬ[NINH2UCq|㒕i\<ԢbEe4u*jNa Luk؝89Xn3=w%X_I]ėJ"1g i~=]FX.` KY_ھF]g=-|5{^H~n2]~O}ь?t[vPѩ)nK@ ٧;0q-zgy\uŌL0h}uF VUהLaN.cyWyѽEs}0 j ,栉,|<wW{7N j>\#օ"9͎;v/9?U3rI8rWĝD~#<>L%3 pd%d&Y Ϭ#mBq#z_GsO4(6| =R4v]~g5z1oSs/ڍjH`ԜE,y9MmA>5/3i9GsSq> oV![ϋۂ?D3ضs=ƸL-ij򧰏wNlߞ)L_JLa%..`2`<%azmo}\0it$kD.&VQn7Gǽq s:!ZZTr,LGWT̜N dB>\uT7Ep{;Mr[,i-4fRC&'3"قHwf_aj؃Hs 7PL] ']I]T8;YrE .MeUքCC.<_.[=̛̜KJ˫h Vs+cQ.v˞^'p(;~RSVEhL FynO,.vNSAE}sه wA K )fqyQ[b;gBbY,8K33Iʛ IDពN@FvI qd E/[BΨFeb)MQOoi67oڱLu7DuM3ֶLm.tyZ}?!mSOo%k0z|-\L`p!#rI4 `哏խvխa-TDv˯fm HFfVk6S rA6>E>ϵށ64t]~jb.0y4r=n/Nq"I<,p#Y^ݜ=}m :0}u8Pz + ˲0v}vguv9͉e0ngY{|Jc$elQ3qCۺ #(>|i_">3#5wX9H5צ*SVZ2t dǎ:h? vh )c= ;~Ot\Th[>z&pi(*l]t WglgoE/,We*<4s`RFQF77ixZrڿ$riHJ([x0mPs0J5 davV`ix\S;)Lpm:~ |#(('mr5Mndo5՝Ε61,ס0- ` 9^Pc ! .$/J~VH7baT1)= ˲;lmO3LYU^.ly~1GL`t:/tF*7)`gX}\7}pTo] C&p\ {カK֭?R>J{vR/؎c?ח9Q:rmvx|CqГi 5[q` ɛ}' 54@'Q^–-\O\i+qZ2#у pj7#p|LN7I0 d.B7PM8NGm|H ˏ~GpqlZ6;ZZ빻R}SnWxG&Ns 6UI뽽nqKC|m6!ƶk(۽]=@,{u>LmS&Pf<[y(o  PW~& KbzH%.%%u4#ؑ MٲU;[/W6죢1H]kW)/u20[x1!j-F/8=O~99J:*.eyQ9 @=ls- [xw).' >9v^Tw&$a4Ƌou5 0z*mPHQTSbf0*d'eGN9;b&1vѨm Pwwm7h>ƭ,[k[.j`@=]\'B⵼,8vY][+vJ(.D[=-2w,~WNsjw^^h+ݸq#ig2dE6s1Lx~^]7 Ӈ+"""""r<lj_OmYWNWԔwqN:R't3 cPISY߽c? >uǒX@DDDDD1B6oߪ'aH! [?M"𥟱v[}d qBF8)y79 *W\L^) ;ߺ Gbo/_y̯~~<\9G|uwo6 o=;~*o@W2ɳo!Lk}-TΡߞ⭼|Έv#ΑF&7r?^gcϾro >}'yp̬Ʒ/RS&ǏQ_=&#[.$| F=+{~[XWi}TlCh+, 13+.CpR^2{?U}?vuf|C|ۮLc}/,]CсcngwiۖLN^|ٻﰪOd JiJMMs?Wfee9fiULrJYN$AlqVvJ㺺os}ߜu:gX!u& Pf]kх!;x/ |9- bݱD!/"""""T@wmpBű}$Oogy[;/ѽ?u9_:<}iҜjt:vx4nug_„ǂZc|+Sn3Hy,_n^`La't2nG߱ԩu˦r$E,j ũW;kb呻4-B8ڦ6̭!=q]w}.4KrԮX1d^{zH؀%IG<#"""""*!ۀw|(I;O'َܸGKJ7R9dl*Ww$dmJѤ_:իHby.fP 2, F dfY5`;ғzJsй/}).\IXkfo̅fPb ^% ߿-dlsY"kv-v.%ӉWzXEDDDDD?la^eP@X>.?6q)>< p <3(N?v1M})];djx>9C0 t0Hбn "]%z d\CL|20 ~w=f雮gŤ[=}g].rtgDqtB64k%Pb3- :N~\^ueZ4|tD'?RV!\ېm_5ekՠUUl,`ɶzBFN- IDAT2oaftݛÈ_pCiN% nfmuZr]hs|lS8r"KY8ԦmU;.lOa0o[DDDDD!V0}'FҎo$+4u +?1Ig1Kvp$x\lm峄%$aq^WzXV,5_\>-FąT9لl#\~9 :a}d׺x6##I m_lCG q9$jO١EDDDDDu//488__\ۤ!ţ.C[peCp\1"""""".;qߕkPV~"##jΝ5$'d|?Mgutv<@N`l;CMDDDDDDD$?EDDDDDDD!?Ʈ`\I]Kb[f 0wd_wĒ7ag2EDDDDD =َb88ـLFjp}̴hFMAcׇ]ןad1̚Ћ! Xc\JLtg>6&=>-0>GW3f.ēCuzO\Ȓ_1Hs9g6f{RVT`[ciϜ{?,g1< p;=1Slj<#u2nC83츄pyu|ң0yJ. 4u#6^ 5k)۳x!eޑ7Ȉ&/,^AHwHc~qs7ۊ,P #u"x|} C߫=Jg97 Ofugim ޓ:P6q ̌Z`Z#.0}ݾ>"""""?b(+14slRT /o6Ҝ?~;Y+*^R<2Ă)XrLaW[W=;Xg iۜd͜Ϙ> v/ɧ `ћ7W>eQ%dqe2+^NlX9>CV#3bp@*Ŭgi|w8GmxTM:'|̣mkMeH_maGr:ݗf޹՘˼oMز+K䎫snd0YCz"f\jT{ejܹ¦Ys=D_WɳSddp*H}t''*ԫ_GJTxFWrѽ?u9_:<}iҜjt:vx4nug_„ǂZc|+Sn3Hy,_n^`La'ts #^^؛H~ͣy2iy&K~Nbx ה [s\[i} ԫםڵ K j:gQxX?oץ]Mvد!3~^ŶM:##ٹ Vr!WesJwfPKv-asZHI76%s;\4$ͤ'Dpkg\ ^Gf 5`GDDDDa*!ۀw|(I;O'm;-Q+aDH"^E0q,L{ؕItW =\~dfY0W̲`ckλzM'`-wi#Pb6w]q͘oN+q7< ]k5x`g_ Wǖ4rA wuY, M1ȧr}6B[#O >"dؤaqa,\Jbs\Ic~(}<\rqaҴQsZu)!ŋR7^Θ8u1M})];xp|x^};6_tF~R4z%%YpsP4G]nUE]$\lOƔ7/7aiԆQ.s)r>0&@ .㒘S7DaY9p 3S e{mQSC9oyuˀg 0EpP>G5N(}eC D[jr5L=ޕ)_0ĺ.~{sKn(M3عh:0uoyX^.ϱgJѻ:9{';6Ѩs523Vz.]dzEcmkQ`\OZZiQ˿OaMO{KQS, )X j?mCr^vu y̡J& Sp)(!V0}'FҎo$+4u +?1Ig1KvaI|Cg KHl*3824ِAJyN>#Q9ρ22tߨpH=ǡe2eY̷eº_JfN ؖ^[B*aN'<›\[3$$Xpk\YV=[RɆ+ 8s& rTn~%Ͻԗzm8>&8~3bG<2jz )?cgǁ|#aJu`GM9-FܚBq'G'0DDDDD |]s˫D~; 76)uHKi:\;0yoi;PkYy u"""""rE7p݉K\ۅRj|WNv}05M'9 %wɌ T.+G&mI|~h)"""""" l93vs<4W-"""""G}?BB]|r9Ķ@ab[SӿjEDDDDDlL^1glb&J21g~oobq:)ٮ >O109ubWOM(~~S2_r)?ہ 03. O)>YWI9Ñ+z&®r}(Uaʡ 6 ߞZ(E\.=DzyUse L63e)RmV}^G1,7KDDDDD)x!3 `["E\}gzϖԜ2OF G Y OBؠxfp58?]d^Ӄɽ-0~`XplOcz3g37(cJVKvo1#s<_58RG/:e:͏ҠKg>SsG8Ue_pʶ {c;I 48TtAj|%"""""RАmj1v/sARӀ}*˔}P'~CF@Fx3;?z|6v޶=-a/zqh)\N~s-VuvtKnxyjv!= b ؖ/m73җlhPfm5ymyJ. 4u#Ʋ{ *IP6>@:UpO>ȬYK~teZL]ߥް2gt7tu{ub?~̸mEHRGo(ۑ:<}>>X!R՞׳ zیhNBQ=HASo6>ʳc>¾i~3{#WN`jIjve= S4m|G[F2USX0eK)j=;Xg iKvظR62}e$Zc1w__<m{9y.%3; ס4T|F|z^rBZB/,!=;&.5*Qp{bD|xm(,uD=c4t'HƿMg&>|<{ jݐJ|[95iطhAM,h`GS Y„qr#Vf3N*'ui`Df]$Z;n7Z[K)).+}9%"""""RАm"lq]"o=q/hH/UȰvckCŊ`FtL2MkۮMS.VGm>7, 6M@tzcO&|ߒ#.KY<ߛ=^c '] )"bxZZ|DG\NIdkQ$] 8+VKDDDDD)R-A͸ł[ N"25:~F8uwW3ȴ]%s*:p}!9z/n>:mPK >rWZTc&b,,, 14|$,3_ܜ\~9 :a}dɹnd\rڴْ"N6\I3ivR%L)ĝ;ɞanlƯ1͉saqzv๗R-61Կݠ89:av(|>Qhk(MLo?L<`gw[[&d>֭DDDDDD |]s˫D~; 76)uHKi`qeCp\1.KN\w.44UHНȎStPqg8ȜO|sX96iC7LxtVG\""""""rBv%}p|uHAU_%""""""-""""""b% ـ]|r9|h W 2mDDDDDD$ =َb88ـł)2qg/_dsy"Nt1?3&]D|I7ڳǍ<9t3:ۤތِr<ΝMؙ03syPu~Ep\!)v~7<'9*1g8c%_/DUE׼ʠ o)9ggOgű{;Wqp6su)-c0E aqlәdnvIթ=kS/ z@a#UKepr$ܪnt+tnτՈłex{[kkt,BJui-VbkGE]`,_GQt̐28g*{UVT})*я$1xZbnPӭY8U@C~ -܃D%*˔}P'~CF@Fx8.]2a2iFΕ퉙ڝwcH3TƈןViңΐq(MolW1kӏ^b OUOlHz)c>_0QC?H;o[Ėl8S˧,~ ש{AfZw-kˆU<91F'kf]l+|@Ej2 e;|]'g9d[ӡz_oM_X |;y =FRmRb ;5fƕa7+#)z~=>><2Ă)XrLaW{NOٱiXI0RӔKpI <³O?%4kǙ=}mw4TaGr:ݗfb5ZKTY|}[#E\0'guQ҆ scf9N'ݶSob¯Xw,K9V@w1=أl CMwJ9|. 쒨l"+P^۱5prf7MOO')gdz5Kwh.|;_,Ԭ`O .ޑ-ćGn&=!Ç q|]K~e 9/mAu,^t]02b(ݙA-}Hص͉w34RoMprqy N =G_vz+7Fw_sҜrM)@~Opגq߶BxcF|O",`2[b %8G\̀g 0EpPUy 7lԟk}qhV:IdZ3jtI p/¥AtD'?RV!\d{9:_ntl IDATӫ)4g;ׅ+w]6Œՠ6$GHj4R饱\6c'wuZWs"vNe<*QBn\87s9|{Nz]dzEcmkQ`nyYOZZiQ˿OaM*}n]|"۫rPdjVFDDDDDPC6`>ʙK7k0}g;k52t.Eq%+nrG&|ʛ$MX,쪚NE bS{#Rw~X~QS/~wvB#Y1\6z W.pjLc@fo0SF qNghp[8xki|h8~3^;dA})d܊a6ts$>|?Mgu%"""""" )3}îCDDDDDD  /l+Wlrr&u-#,d,+aTM>5Rs>לpD\Lz"s\d2~޴kq x&vU4c 3W..[2᧭m϶|ឦn1t֏l }Jl);gSo}?i*6WeDDDDDDjU>3OFlxʼnL8;7lRKRNc3G0vyͳn5>sxƭ6=n8jzC=F|_|~`qGE]`,_GQt̐28g*{2RH!ۮ,m^g x9ep>M̝ߞy؋̝ǡt< ۾IS7i**BzR}1nEiE %:3gEW\Ǭ\Ogjie*''u<[?[ު c wcGjsʈ&/,^AHyOykҠNvub?~̸9l+|@Ej2^5&"""""W*p@.CkY'1Ù|m/'ϙmjJQ0Λk=іLՔ Lƒf szuU!\,?ORL6͚q&`j1:QȦO?♼۽ wŖ_X"\X~Ft,9-mxqHl_mXG?/swTN÷.&Rby[P8 '*azє\#nfœx3qus 9) $Yq-b ~gf"8|8\}0?͋&bQQ': S`]وשQ]ҝ҇]K؜SDDDDDDO(x; `h3H\?fl6GSY;OϳyM%, 6;+J:};cz6m$`,ŸQa=~$G1֭>[T.ZG(QOv,~A$9Y.dgFŒeo+ΞR^E 1㬘4:uAdV_?b1xQ {wwTViwzg bf3#f읦9HЁ;ń ̌=E(Z/}8ӧqVۧdAP1#>MP}0-T\DDDDDP.7gSH+;9p>7Ftk$55AᦃxdkI!5Âٜ}wpik!ߏUG,׆6W{l p$8{ ,XR~چl )HcK7a0oޏO{6>*LϿɊT~eD?-o^ͤDs(2U9oǿahZ@#I9` Nx?ӜݰJo|>kk˹+oҚt6`ܽƁQ*}Zէ3q!vB<5uaJu`GM9-F\WBIuiL-pJSlA)0;?n6wÙ/^q[l(Nc3?ߌ_DDDDDDHnU"k:xԥxvqeCp\1<ɀU)!Nݽ.""""""E7p݉K\ۅRj|WF4d4lܙ'32'0>0Y""""""O .+G&mI|~h= LDDDDDD4d'}p|uȿI{?BB]|r9wMaϻobհ/3kaW%"""""R,d,+aTM>5RsyD'b Vyc&JPж; .vU4c 3W.~3 ^- >]"ⴝ=[Nw1P>eML2/ݻA L@?f^+"""""'|f:3ʽ98AqXn~O_nByӭ_ybi&=d%.م/U#-h2S䥓6N͖X6La+?uk7WDDDDDfȶ+K٠^N$ew:/s'fjw="s絁#q(]Od¶/dԍDJ7FZpuw$.Dj _wZ`Zo,ML3~ދ)[`2! zb~}EDDDDDr w_KW~3Kv+N98ƕA|7o%I%Z!q7^*L Jԭu-ul'g븙-i<۠*Ӕw ܱo,^(.z9uPWx\&, !:<xw=[1l 8`+O;3l)̕\פ|8 W6-xWfNq$&L\ukWd\y2#פy0gHXWDDDDDC6m56=}24KrԮXot:vx4`Bn!`jހ:giPՉIlϸfWk؝.Nzݩ]+TW9R~ >LzBkG=znN, !7> jFLymMɢ|I򘟉ry3BlgٵvZtŃl9C`g}EDDDDD\  `hc,3M@tzcO&|vNfŋx%;L2M3Uu8@FvFY,UB~%{`g_ Wk9s72fs,|ݮ])Oz)]08Eз;Z;-HM+ϯ%%R݊~ه}9lr~r?̨Xpû;_^lO)"LtFG|;oį},'cv񢔧ΚMgtӱMcUR6Eeb)+e_an؝=@5}ſC&CQ<>d՟\1V5<5x]JF|ԛk4O:_c){ c[WDDDDD$w.dB׳)zǍ8o#:5pAD2GÉal&;Y5nGʪ#dkCuw`x6@8f3vpk:>®bưi3a/F4U`uu$c5 { >w?/#[88{PV ZUBkcR`!]f&W3ȴ]%}ϮJ& />qs޹he#X Sڧt:'>f[|NΥF9|?l|;} CӺH΁c]fvr4}Vg^#_CXȄ\y՘%=Yp&~9֓Jemk)\\>-FąT9ls?,ZIU)҈xwcCh;l /%,! K>^m9Ox7&gIHX&F;Ǡ9?;0;Bs k%|2>E^{ ƭ':Fs~d+"""""|]5s˫D~; 76)uHKiځˆฤ7~Kcv5"""""".KN\w.44UH쿅5$'dGCvgġ]dfy """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""""""b% """""""V-""ޝyY03#hhi? 5+,s)=+25F'z\޴ӝ֦eor7ܮԴ0O>DV/iIicRiyݟ~H:׳isIy.òuMWV. >xI90o?yȥ~kLz3V/ʸ>wiP֬ǿ5Ϯn NݝϭvS[~|ns۲1r51p\2iW3oΝ|ڵa˕7?K{wFwNf6_&oe;vO6S~٣^0m9ܓuweE{f{ɧMKg>߽">{Ϟ1eIim?8-{ؔznJ6*ӕtUJv/yexQ 1IDAT֕Y+KyjQsd$)[IMss_Qcʀc3ϜygW۳兢2C韊#]߶sHGg)eseNmSLKJiiiKWYl5u\ѿ&}ґ|]e'!Mb~uo3}3?7L`v{~Wm ꬼY;,o}O]Y9ݵdA& 웮;IRSdV.妻Lͨo^3.}{~>ް+Oy[ސ+-9+ssy+[#sԐ+ˠ=_]Oe5K3{T7mwڻ٧ӟ9k/p̯'p8SZpm7K~4^G~wCygr3s'׵KnaI*+J6]o(ˬߜף&1͹32Y{Rθ#zqIYs#Y71,/՘I,ȜG3Ls5+?$ؘMݝ5Oʬ熙sһǺϬ]3]o/G13yϐyd,[ݙ!ze-ws^Z5?W_l?'W<:9s92RSޑ 2Sss&fD\zӊdxku[g͂|(e'R[>ݯg'λcU{HcCS{]QG7vܥly]|/+("0}ʙPfm};sչ ˋgrqx zWx@AD6Dd@AD6Dd@AD6Dd@AD6Dd@AD6rsObZ*mmmSyE*//Ouuuccl;Yx,_<=r| [jUӻw455m鼢UUU%y;mdlRYi uC;mmm=rl NyP=vߺDd@AD6Dd@A<~@TS V0"ݞҼJz"i]2˖feY޸2t$;μ3:zsO=WTr P՝֕Krmٽl^\3|99mt>t[nY&C> ]k4wH[sKZ;:S*ꚺTU,YڒֵY]}ҷ.Uܒ*5u, 'iD6/b>q|>/úd|ckSOdks州HըCs _Η~8T'w~.omv])Սqrv\E193ge?VlYT 20;WdeغGߘ&aJ&wNeETgy4,HMjkRԤXܴ,Ã2z{3zt\=âl^DWVjIW iN kOֹY剅)90~}Y7>ՇV)4 {xN-9o*^[ D6/j]cۏ90?9,;eI3K.ueYSsdt,LYWU֤kWr1xNixV-٭]fM˪U.|D6G#;]YmwQu;ΨJ2k=Y5|tM:<%7:#Mvg|=l\К (#AķȺG~K/1W7C8*8`dV;ȼ9 zijjSyEɠAz"ĠAz4 yi.l(l(l(l(l(HndɒE=9R`ŹIENDB`AntiMicroX-antimicrox-b300273/other/appdata/screenshots/advanced.png000066400000000000000000000752571471077622000255400ustar00rootroot00000000000000PNG  IHDR}홆$sBIT|dtEXtSoftwaregnome-screenshot> IDATxw|unv^ ';CS, ꝧ'6TTAB[H!neEZny=< 3~?3>6y;ߑ`eʋn>ONapQٶ] |O}>k ֆ>1)))OHH8#!!zbbbb[;(g۶`+WVVN-//OR}&x%!!a@,Qa0 (&&.))ǢRRR/99>m{@lV(7:[e- }n>iiiߥuk;B^c㸸&$$~?@444 .זoQxr8m4loQcf۶]4a^-iۢ08˲ l6 ÈoI[g[Бe8CtZ?L}Yz 2!]\.:o |6+ ZTiw=j@Ir6PNI u_)Uz&uɍiUWߢNC:/Fҋ-ZUZ3vZŁLI C;:,]TFe}'W+a5xcԅjɒ/gS#K7i uw eWjm͹˒%Kj $na*sܛ?;?6ӐNI kMڌ} 2Җ?f4p.h_rNUsa (}#2b\OGT̞cúw42}0F/Ò1'p.f]cBJɭY5'nV*a>C%2Eچ]Æ-={~xtQ*qKakny-͚?O3^iU=@_~NNݸ&~X`vzNS_׌W֘SeH2Oc_|'>O?>7GOU瘬#uCk| vea+z|}s_%*v>W?VvU:IJyf)a\ׇ 0 [ZK}ſ=xlLQd$GgwhXu^sf}{?v`$Ci~|͙T~*3MzSfǍͣk_}igclHr1G&k;_*=D=vFu[w{D[Ճ=M*[}㕱w/$i\={7HgML6\}|x,KZ(OW;XC5rwnT7y$KEsgkA {Ώ| 9ԬeYtelˡ/گC_$[D~G_1}n?t/ޤ^XCiDvPKzT}T)xz<㚪U ~.xrÌسS-]v?+o~? -é_\47S%vN[u[]miV<:ra6*f;b>aI Fbwg6JU0W~Y^32;+t;g;wa(Z% }]:Tۚs nE[\yOWr6555|>"I;?!SEAG"agM/ش5QO8I mE]d~jcufcYUw ݹz PЊ«ԧ -V]eBrgnr[)TUR*Ԋ Vh ;#UnuZl,Og bvPҵ3~[[~a*Uͪ-71y'x-Z3S W/\'S/ߴݥCbՓga/jaQv?ď*͔~܏/fjAC:,?>,I8 {CC-INlU9[ +?c֗Xgg }5w'Q+Nfjup&={:-ϟ_$F-;}QZD4ڣ-ue6?5Of_Ж^ kM, 쥡{ɬ\O:/B:trC7?yq:3zfL"BXCKgQ%I?~VR#.u /r 6Kg遛kφ=V׍3\P^s&ޮqA9`LVyVթx:Uڭ?cf'Oc^LPY󑶛ܘnݺ'&&fud(sQrHlݽ۟ߥ-n_UUU\;n*Un9tARL gLI->a4ʣ}.P!ʕpzU{ڀCO%j!e8C3- 0Dz7>Axz@"B>Q D!B(D-mЖu Z$''eh.(D}@jBέ{AE@&$%L[u q>2%:nB>Q D!B(G>.bhc훙q!w@nB + KVkGW_0PO Z@lt!=:p?b֪~ Vk+amJL(9IccRv&d}Ǚ8(tckԠDuUQ\W1;>6CvQ;m%gƑ]t`S%$\.YfI|͈Wӯ߭#3+*%SfX;3^i_~^')kuzzZ7A|Tt^:$˥Pyf\Vԍ}8N=@#M)}f ק.=w~\ϮrnM~\]:t {>R׃z1ZA&U9F%vڪcon?z䩵^Y:RK3#_Uu޺ G7mܗbledjQ}4X}\I:kD]sTاOnKi§ JU'&xao]RV& L-_'cW/wY:|P~#Ɣti:[5=no:]WI˥'vP_kd:kb6&_`KHhw>U΃2u^8˧:8Fo-:I4WЛ*ǧPjh¥}B3V#%*kuզͶ7]x+Ɨ5)N_/hMn^H4} uIvP -]V $NM$lB ! uMu)so8Dn~7;뫩q$nx=-.;;]3lOzkDƑYHzkIޘ7'K+hڝn_ps϶j<+NR$j$klm *OJݻ̣l)+kБ+jRs6߁i:~@W9tjDADV>x'۷^fݲb:.]X-f&J0ź Zzd8}/RUfdXZB?4B; ûJUZ+9.ߣCWǥe%i;[7UzpS7PLIvLJ8UH4pjn;?C>Qcv~\-{Hhc jZt#Tn322ZiNNOzf׫=)z>^l=>7vNNN{¾7Dl%3H KSTTT\v{zW14,d*BkP |@xq@NT^X_ԚH9Q\}4;u>H#Bmv{O~S3}@"B>Q EecT漯Fz"] @D#۷H?OOqt~|a|H> S);Dx3ы$٪XQ%t4mߧwٶ-`-=Y^{&g:}7}J-)~Y3tHx5Qmj_9ݬ[*w#L۱ ϾgFiH$׬jd h_'X:sxAGߣFu>RwsR+PO>\nYgDBiF'Є"Is9]0Xw짃?ŇѴ"I[#)ݷcGhHJMy}-.2S~vpECuJn*7mJFTHc}B$SY۷1 _|WnlL"JV|v2e)TZ_zlϔilvJrM M\j#>fSΨuڭcU=m{Ш>}9~~Q[Ǫf2S dh|}I+`_{g-Պ>7gINe|Ufw —f2 "ϫ8Icn9^ҕZ̝?D+NИrmLIm^ľٚp]qs.{z^]H{Wʩ/U>㮶խ[v}zUI\TϨ.aF/ۭH[x<$Ϸpz\{\U)hT}z0 qk=/դ9롑mr\.cvfs=ZQLGmܮ%"]¬g߸Xw:RP?0ZWXeƲ,!۶#]06]g:m}=zaR2fmTՄ)ٔv왏ulU(m:}ZYӻlۖ]Do {\Gܦ^ŷ^G Hɩ̙jS<eѽWKyZRlm5ILZbK=Y^{&g:}7}Jy@v5}4ZEo<_X9 ¿ Uiн#X:sxAGߣFu |w|zZIPIZ1oOd/겡jthzg^9.~zy1t{jkOkB m#\+TNLEkuAu!.|cٲmEo.ݫxYeEJV|vڼ/Aq j](u"~{_;Fzs+e!1:p_YZJ9\:VӖӗg[@G%ɧ֋FauͽA;GJyѩ;z>n$xKWj3wj8TYX`RҼKqv* KXӡG D~ngy9ٽPm* %g)b{7zS1l,ZD }J^UGFKk>|DW}N^_]rmjm[UdupT bO*k4n=E/^z ɶW4{z?znq\rۊ=E/N\1K[>׽gJFGc\oK*}9r+3}mҺ9O+TcN9'Jwݑf?6/xg+2RU[UlKބ$%x2ڰ^Νd׫\FZݶU)`r++o|J~P_-.=ȹ'%48U[ %?E 4oe%ޝБ@*X^| :`@eW"]n*y|u1 ɖ}.f,R٦Qv0 XЫ_ߘq 5ttCO_kE~Hvp+5#=㚺2KguNIil7xup,-[ p{:۶7^áGFKm5,GOG,vZ3Uo{.?/z)ʾ4Λ[f$V#uxO$}P"c?el^ζ7 9br:px%&xvډ:4i^}bfK.E_?WC4cǶޒ$KSU/K1b@LJ~U#M"M4YZ}\tFSѪ-K 9%;]1u*Z_%#1M~*|YM]^d>yrr(&m+4u3t=SU<*=p>@vH@`W(sJvG|?9R1adܤ/ojA:4e^[XސJʫe%dKO >Ciq )ߒl94 j-bkkԘ)phxV(? =ZÆxnn{̶C  6TjռɚRZimwCt6Tϣ"ֆ#ʋwife j+SEÕޖ\[ɧϗ̻Sߨ~u <1[+Z1:u^G UWƽ_UPZd*=Gߞ~NF0Kt>!}ܭfm{l>wJO 'ۈQb5yj=ӻ:,Ba`ʔAټ-5ޤ˟[ڝ)SanZ.OOa/%;M9wOW!|^7M_9m^tȐ!!م㼺u IDAT'*XR'ܫ'gIg飛/8Gw۠ kTLӡu9xDBUZu=· T}ϫk.>AũVVպժkl=}NCOeUU_>&~'DZcn322ZiNNUQ&77W jMk7eeeu(JMMmQu-J-nXVZaKe7׎Q uy&y_D6N 9jSe)u*[3k}p@]ÿtㄥ ph6i'[hTMR"vSTQQL0VRstmO?tRՓOy;{nnLR{͚&|^}H'e;j e꾹 ;$Wu}2,½oim'ka}^OcRyK5ǩ~qj螋R+PO>\nYg''hAiHe Mߥ翪C;9&I :R!=}zfcuۃW£ }u6ԫkc63},{~;_~nXϽcGhHJMy}-.2S~3WRCj-]vjnl Ӛh;uL]oxZo[m|QL}MY/=+4g\ÏU$)ֳoԶ)G`BLCjezN[_9c`YѦr/33KOʛ[%(F][Mb.?E*I>ִjC\.n֕j>W\ise PanWM.aNo?=@쳷U)\)_C6~-#=WHe5bIUF)vPV%+>C];ZKR2R*-:zU]]-˲v˲fp=ZG穪\l.'ףe*@S"]¬B.UYr<*YPLꤿ]W>*kK3KD5Rb4 CUEKZWv)1Z}oy-֯oXEo~}\WgX۲3rvXUO[#4jO_"?pTUUH[UBBBh TeX{2# ??e K,.T55TW_?j߽ґ:Z-S_VkKjStϸ[tk7=w[4[3>+κ_wxey񶹓58p]7ϲk6h5zZyu'i-+XRSgH=9M.JLLt cHDLswMIu떟NsrrԷo] 24hPmxM+{CKV2st {nEEEyyy͵c(D}@"B>Q D!B(D}@"B>Q D!B(D}@"B>Q D!B(D}@"BH7.}^ HfAE@.(D}@"B>Q D!B(D}@"B>Q D!B(t@eY.!i())&@iibccէOHB(==]%¬RG.K.a6~>߸\.|v3˲d iDQ D!B(#6`vK T__ߪpQE:ZXUݻۨ"FXцb9LӔa2 CƦ/M#Z'cMNa2-_-]_EYSB*Se}L>Ё>M;LSoP<ꍱ}.+ UsW RL{졸 :04eƖ.0`{V*JjY~C%xcdRF5u X. uHW]u|U\Bۇ>y||/OϞS9kEz?l_ez*_YO߭I=N}{%+TOCVL+5[F)vfTS8.뛓4wh3}3 |6{B$)=S5i\V,xύid?OM(usTN8FJ=fҎ:OMߥ$HWn?o>l*eGȟ..ys.ҁOKb6SMAagڵqjᓊ{K]^ފW[F~ /< )4䊍NaHPP!)Ϧv@XcAN;V:w_~8V+JЁ\n_x_SR0+NR4: ǣ޽{70 sS~CX t*!!v?j}@"B>@)˲"]`7bYL}cB <`F^oIYRR,RCC~ulgt*--UEEEKDX\\}\BE|$nJ>Q D!B(ӻ6RUU:YRb^}lB )..Nݻwt)Wiiu\B *++zvU^^rx$mڞ3~X3'2ۭv>@Y%0dvK& h5ޘ}@"B, hTnnm.]CEZSuuuR||<OUPP@f}MJKKSNݿfBu*+#9]InV#~/ESi~*v͜]?guNьE]]ݖ/'Il,U}:\7['6ή,ԚUVMCZۻ_@[r4`#C~VU>(7!I Bkѝ(gz>VK^zlb㓔bB>IڲhsZZZmjjjTZZzyb>N?6ZG&gZ}3 = \-<O6KRii.o ӝޠkx2fkZw|]c#I1is*h~叺gf.t$>@mV$ɶ-駟~RݕhC[}|H&?2IH9FYCZ$q>~WhEAEEjkk%IՒMS^^:Ijڝ꒝_UXi]Ud HSY+~ 2LG};(((ꔕlЧp`+ 0e9R(hZVBPt)-5N"~!gϞӪU츨s5L!ʮ_YA?_3No~O9|ZlmIpd@A@*..nP'66w{i4rdbMxF mzOu>QҕZ<^=9L)C![}/I20%ctD-z]n322ZiNNUQ&77W t+333e_+==]ݻwoMII֬Y}wt`53}[h͚5o" ITaaaNbb"|=@ԥKu%eVB>Q D!r4MB!&cldYV.)Q tH m1 }0KJJeY.Ae^>O:6wm --M*//t)SZZZK]Q D!B(Dxz6QUU:YRd^#]JDyg!+++S\\wR|vGy,R>ªR^Wn[.x<6z(3~<l-R |>\.Wfn"]FH|2@XY%0dvKF Py^$> }@"B, ʕ+U^^i*++KYYYX"l󩬬LxAM:IF'7SӴ/ Cs_5{H{L7hMĎ@KNN'Tnݵvڝڵv@\Reee;l/((PAA{<ׯ';kìw[RJW쑮RVJ %KvCS IJsiΡ5 ^3܁ %tPKp=}DU idGwQU?wf2I&! `(RJSֲV\Ŋ.콢U+E]\u^A AZ4H/23EZBInޯL=;;9qD8Rco(Q )Zihu^c.U!qY?Oԃ;'-wjڣ i;T~zs+`V͘Tnz*YS1\Jک6jl9܄;'-hE|flOЊٚRk=)F]"XoH{)֫UN!w}?u^2EM.U8ňR߻.q>jO$> $75{IʂL͒1MSlJ: >WkLI*ֆYSɬɑmZJp(G҂Cf˸Qz}[Ҽurƿkf$ɧM3kg:)I65[fa~@~WQ+>e_BO_ 4~8,Z(I=r)S*k4;Z(PUjguz0wV/JSV$IZl=U8gR'imK*ަ5YBԘ)[䳇E+u7;5Ú:ﵣ4n!N)^ Yʽ jթ-ZyQFQYU6=@FFjb+TʦeJ9J]=Ks ?_ܠǪtZ]&ek35 tݨ05~mU8P=;74Z|(77%%%SgMӳkG^Q7wj$I2?piUyRjjˬ'ige_Q{+]m}P]X;ZO-ST_|- _$E>.?5v7GLA~dH2}yq;pL`NgF4 MB; RDlG^9lân-Cf5n\ء_]o@Ss֚KoEަ֨4~.;գT9ƻ =_LC IDATLJt~]U<3ڟ6t-^(ϥPT (o˔\ T+$ddvwko[3T=t.YDkJ"s2 5= RJϓt*2E%+n}/"㻩[G s=U}M-ݭg{KMs'_Vԗ˞ЃOַhh`NmɓY%I>E%=1.=||q.ywY[OV{_O>W=D{ZƹkQ3w~opۻeeǙ~05r*I&j*d4zviʧ7i~t]6 L.w\q/Q)|)P*ŢqqqѱU4))I _`1ڵk˨ tuHF=]kq]`%j֬Y˨Q,_\7VVڵgm߾];v$ôɷzu?MkpV;3KKv/. nGk*8gr}3}zuMAºw!YB%.;TDLS;ҟhet:0"M.vi-QmZt\e^];NխUu[]G9EE j$#P XW;륗_P(1DFzšŨOV=J~Y+{h#5[G>7:>!W¼|ze 2BuRIO Diwe(iUԞ[ŀ ꁎ!*K6CYZJO=z %oJVQQdH!o77Wΰp/,WS%딸p~>~uJh(,zbڷZt~U#LG[$¶W4y]4A+s+i"P@=W\,#8X**Se>D(eܹS͛7!4eY*,=̥EEUOYZ=PHX=m5Ko8Anե>Yabysf-=pJWA8nNdj'/2M~$S6sl!ɔӔݻNeM)0@ R`4[ҪFөl,49pXmm.4{lWRȊ;}:mAAj'3HIk4^{}RSS+׎;_Ճ?$ kWhhcQrwQfti9}GK_١Un{<u!!ꚗy=?OvC{]z7 g;2\*ح aak>{~K|`jo/WF%y7iN5#n߂˦_~OYy; ɐdzC z>P,iPC6mRHLukU<5Nɰi7{dͷTrL[yw+1!^ D)k_]e_;=@5t9*))QDDDۻv+++K999.`aaar5_B$q@.K" B " B ۻ$??_. 6M.K5oB$VXXZjR,/Pr@PI{g tZ$88X5Of0 Ra53},},XXWz5TQyZTBFd霸=йZl!>p{CA6zƤat23S4:++5]yefyuԖ!z{ZT_W˗Lwۘf)3=MiJܣR[ݢV!5TWwi׮*qX 7}7jpŗfKdn Ox mʗ^{ASW+ez:]"7eZݢf '1EvTl\=ukZ^vp!:o 5XwZ70>`q Sc[N3t rs O-ЕgiD {NoU|h̰z9kxq>K}@5vw)_uckɧպiÂ5ݨL([P.֭cl\}骂(q&};7vEGGV*m2MSwf}0q~-iU#j?|gDe>\p:IO)_xWgMddGjɘA: ?Wqx]@}Cדwe蔄jNODnRMڐ4O}&Sn~|A8ԼYc9q=}Fhi]~o{ZE7T8ͩGwmш~f}8_*~  rz iR ũijG!Q|*-Γ+Br$+0[O)+@>o>&M]>yBCr}1)zngJ^ǔ: ٭˵4}l-/ 5cuHvNPK5I;NU-^(+?glC,ԗKML~MCY٦ĶU[ryM"ۨYT2fʋh#w+h}Z/r Wlڭ S^Ǵǰ>͚gޙEghX߁jausz.x~! j׺HMc,KvSiqm_.4UZvy6e#ůMx|əUĞy9?CW&{wzw|U>qN\^p>MnASw^Ey2moN l2d~;JՒ҃m;xtXŬ7UNتv du5e@z}=x[ Tڮ5*QNjFi;fIlo-ZG^t@f͚p?i)))술,h|Kӣ@Ι29 74_;d3Х8I}d;FrV#5)Ӱ~u fHEiݦ.IBt&䏪x3,},Xf6M>O65~^,TP @-R^^.U$Ydd<<~WII<"""jtn[YYY t) 'E>wXXXXXX:׿DOS}md j7zxkbNKSO&CqB^r*IS5 t!LJ@-cčo ֥*$; i?qv[i-s*'5YzJ*$B9j)o:8uYG%;ޡb܁bwdks7K0RaNoG26{VQ^ӊgc:kD]*2&WiOjfy8{S>^}v>]pūi͏j{K}1jN={.|Y~='}q1oΑcfn2jVP.~^h?LPrwRA@][uۖ$;v>8B 5i]>a jcI^k׷dզ}{ۢ[)ٛ>y^N F=Kż j!WԘ7ky*RnQӺ h-z?v MDMOBN+._{kSIŕXs>]ͳPӑBܪN)_kڄm <\a=Pr^xsTr:R6zGX"9q3Ѿ9N:}j-Yü?ky1}e:GM|}瞽8SWiv],a{iJ;CtT<9q6 &]FyWNNi~yVkYZ'uS_JtFP혳@Gd>%2cDFIo-W$Ir(vú+ jҲC9>FܡF@7=~Z7uJ?TB#(Sהa3ۚw]tSzgTL c rԵ?ֵ:hC 5S!Gs{͵kP BR#ku(J%jm9ԣ4?Ee&i0|A/VJ\"{˻?!1s=5O:زtGּ`uvuQ3~1Zbc(ޢ̂fi{ZNԤFVPuIiy!}5sr~oz$@>f}2fvhTr ]W߯{GW5銿5=Y2љʭ&iwƦOIZj%4b5X|`WQaVgqiŗsppypv<<cN|~p>)?Z 흲Q.ӕzSc5}' 7:AuMj9*(TQ)S9ZYZCM#ng RfS EP؃C9lA qEU 4[2ҚJ=S96jb|;ҲuLYkiQy9igi5wn̙]%e*7AA'\iznRwFȃ~y1_zp veEkKOхܪ;GGݥKOhs=;:^ߙg8ELP"\9Pg_!/_;WO]UziKcn+0+s\mR|_˘zJa=}W}4UYxX vjsn̰?W}5^(/^ [%JR-ݦFjMosStCeh444sA?tz )q뻗5ŋz|Xݟ"E>+ŒCkxk0.Tw4L$oV-^-)Tr\.CbFTJ-RciRR*bյk@fj]D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A>D`A@ *..t)fr)""al8{kqN>lUV.IMMUVVnqmV/#p8tZ}`)yyyr\ VNNNaBCC%흡g? gl8{k:q=Xh%IDATxt:]*?c{r0S]Ǿ_9g^s?`TQ\\\jtttlU;MJJRBBWXLrrv2RSSWHZZ5kalO#pNOs;O8|g\c>Q>ܹԿ@qB4W1#8A1#KP{PG%Um }NPm }a/74;?t5jPm]T{UYH뿞;_Nh/BYUq}ZgT\9KhɅtFz-XAs8W]m~t=:34HfluEdj)n[Y> 2LDyTW H|O_.MuI?߮O~]{j*h1B7 j_?Ҽ4K ,Ut1r؝ uiZRV;څ 50ׯx T {X|W*:}jSJ5OڵWF'9ڢEѣo7kxq2eՄ#t㠖Yu:XxHw}]ePWj۱3gn%:g؂]sj۲Uuɯ6qmXZJKLK$C+߾ް$ v{ Dbc͐LLbSejɚJ#aG>å?f&)Xe*,/f} m߬{MM aDѝRW/ ?vW֤9juSzgzk3n̲TaQɑő.LElRp\Qz\Q.-JԔ)S\or>[c^]=hҤG?WQuq<(A]^_P!}SWSvuy%õkTǾMUt^A]w};Z ܮ>QYJtWε=s_OBƤj]*%His~cZE^7/۴,TQH_;DP6}Vm?o^/拓黝*N ~'j6޽,tyժNG}> .Iڍ;;ߧ=4K,҆~yp2u.tS|93_sֆq.>[W6we:;747]*yžQn$L7/<}Yڲr%`Z퐡h#IiE!r Rvg QPSEYz*3UI}vtE(@}a|\?M|wU8PWtw/K[O3ct lI{7֫ܭnAr]PavG{Yolq%PL:לi;+<mTX\\\jtttlU;MJJRBBWXLrrv2RSS2p jٟ֬چ=y9c_o)?####-%%;`I> uTޅT8BT8B8uTm]R_:6.ddfmk|ۓ<$͞=g90;'QFqqqѱU4))I _`1ڵk^SPP] *PZZ*׫?c{r0ñ?####-%%ٱՎ &x7(!1K(Đʼn@ $H@ @/\t lut+[۵z_o{yٞO$P@@>$PQ7lШACQGՈLۻ H( D} H( J3=G^__ߌΛ3 s{@>$P@@>$Pigtt4j^9i1D`F 3K.UjL\n|1###H[[[g{Z{{{]Ո+~<1J%Ɯ֖v0cjZRg{9a=r@>$P@@>$P`Lx]|"sL}jWƶ-߿9[ۖS[zu\l֮?+Jt&ząk}Y0ၼn"sC}*|G30ѕK3|+Չ]SkMGwoKiJ-;G3:Vd)tԫ362ґޞt4 oD`NʵלkS?.&R;3_xX9?#z잷(_\zY1w7䩻oɏ׏zйC:R~~7kG愮N1oG('SsrwL۲չ[s;rÚf/YrrUV"m_!#.kϊf乍r93yG'd#NʳVe9fIdGʦyᵉt9OSl͋yg1gը3-Y…}tR-Z4k)[lI__ߴ??00>GI@>$P@@>ThnnNZMsLV5o?̘LNNsd:::2[fLooo*J*JjlתjٵkW*Jzzzr w3\.gpp0ó^3raE`ƕ ]$P@@>$P@@>$PiE# …Af [IENDB`AntiMicroX-antimicrox-b300273/other/appdata/screenshots/app_dark.png000066400000000000000000002366331471077622000255510ustar00rootroot00000000000000PNG  IHDR!v2*sBIT|dtEXtSoftwaregnome-screenshot> IDATxwTgvf+,uذł`QQc,g4$F5"(* ݙݝ>va+#<=nv|9G5'\=<0 oWv˲jp8Q8~!.lMB8opD]H$UUUWTT&)2:p?Fq_<W*|[3 CappT BEEE[G+kVV1pؙH$dYV7˲L&Ŝ~@**6 cH8ّ;p\{1''gD$qn[`gH$x<;|L&;H>߿1=L3F@ \Б;x9FΖ2n{3=}ydߨ\{z /ϬiaS1-z>Y"nHk4&~mv";497u?oKFU+\UQ!mvErۧ֫kkujoSr ;C}k{ƮrrH0O+w%3_wfےqʩ-,L 4L =FÒ 3 ]6 :y9swPá^_fJwu?+Imj{ҨNWղEgZp?z2@SIe0R$Iy$Y&ޭGoQ蝧8>`oO(ab`$0h̘a>Eq~20 F,MB諚>{|&gMl=d>6F&UJ64X]|ƀ?,GJl:h|Gtߟ+}OfO >AN}~]~&>n:xfk/[/Y ;,?{DO/S?顫"}zenk`'3[Qz *tr}&ޭI7h݅Bv13LZ>w6?&=xFNɔ\=*꽏˷Y)ˈj'5Ih֤ZB) 4'ϻP$s(Kֶk?]q,ߧZPe)Iro95>t^-'FlK*ѧ.y4jeݔKh:LL 3VCBjRsʽC}Auq"_ab. liWk5޶JsM7 R]L<|,M8mj7uU֣trNhjɣV6X0,žWyEE)}eݨ[6<~7D^)II2 C/U5lL>a Goip8[ Q $!9Hc fOō;R:t}0[cULIWg)z3u%f_l+He+[2)YQT}kzeQ݈T,)_$H_^ѬhԄW^vos:ޑ*6ZFMM kDlL]D)FkS߾w>'GOIX%4;6/kP+Ysî.${R߳ZZI>:Z/Cw8^ռ,ѣ[({{|.O?fwi㛯%ǰ]0D劤}oӤHLY#!<4JkdhP=UR} Kz_;cˬ4ӷ~Jeb 4MB}69MCV45C7Q*gޥ7%܃?7|9P8A{ۖ__ F_<6Iyu7>94UmDh!ھg* $C3]Z3rfUƵiV[:||0ܰf͚>tLBPEʦ !F@%b^zeة5)|¸M ".(aK[$!Py@R=)ː6&̴&" .,f%$xhkGI$!@ZiAIFt8 8NC1H  -HB ҂$H  -HB #./>GƎw^֭;:N躧{S'k./~4_=W|SoLyZ{]|D/:r}o]ɺ}pEVeVZEղVq_{KbP3^INav]%p>N)C=@oP+6~`}_S]Zo_5rνN x}v NzT^qKr4wtN~:'-}EkC\_h?=|z TR?~d o}r"2O/SoA{~y~۽ՅtbW.9\LwzZYU-I jʴ/e{vluMy'UYKe dҺ/SE4hj}hM=^#3{RIk#pRjdzdjc"g]vS{V/FnuT߱궱m*=f L՗UVaCv-ؕu]6T'3\ y]]SvWJNպ4$Sfql;jY&j^-7K iiqCm*zʑvC Ŕi ֗ X’a*߿XKuy !jwRI-r&>ή9Wg]uQ)VX_Z ؕuY¾:\?v|[x]y5&O|!In2:]UQu6ŷ-ϿҲ \=9:z܁.OƤ^mpH-J"TFO5BKO=sJoTazpѥz뾛{Eꪋy1*CJ&6K-uuQ¥C?Tf볆%lg]:ȱ$4tU:|zҹ:}5=twtj*l=44fho%9`dC~S *;:_+淊  kC3Tljlc.ф=BU*UJ)]RꌫtTi_#ky4PVIJ캺& ;R935ɥ:z:6kI":Yo^C^VZ߷E[E9 h/mO岤ۈоW[nEk㛺v&^~&\?NحrQd( Sr&ZKJl5*՗8T3uiYl]~Οt6M*vU-LAAAa~~~m`z4 W+jgm=)kkpf_5~ݤb(nr2si WpC W))XmTqK9rwE'u2µ7/d0 6n\S]"/h(ڄ%23r۶|(UUT+(H2l;]r-ެdLpTdJgc;}/lGgYIEkNrrR 9iPO-7$Ɗ*aJNH[p#;2+Sh+` ֚0L2wЛmԻ1D֯QiL<5tzz;H+m}Hx\5)>21hU6l,R0xG ȑ$"•PTXN ~.|/l +HuKJTZY*fʕR\! Y‘)SNGnm-%c#1l.9U$n˒!I\ɔiIRRjb)I)*Tay퟊ו].Gn)irrlZJ* :ewuvkSެj Uwo[=S[kjr"z]b2s:k2ж] sMn)V^j$ێ"*_Jb-mʰ+TTe(W׎0N$6c)^]ukj)RVwڨuJUlz[eh2 LʧCST*Qwdr`6K]<ӓ>*mTu6*Saox:Uagh^yk]SEV-WXU*ZQQ{fLԨxE0/{xV*V8Tg 3sXu&"A|h,v(wkm}0ԡ{p^Ӏd5QMMB9:!l,WTe9MI +eʔn[gs<5Of}bj3J*SoJd]vm|/p=@ J}QK14IB.Rx*)lpVTmMX {  A+R(n7+OyY^UB[*m\_]eT~~N),Vq0vjoƊU:Q7͐e%Emi쭶m:pjhWm&!摫dZ$G@YْPEE** VU&nu7d*'/R ssD8TTv6̺dI״] O(#+-{'mKڥi vreA}ka2Cg]r$QQs!`H4 u{ԧ_Oy\Z_VUMLyu͞ۯ<*%Wͷmdf+L@v׏UdZGke%S2$%uFm.&wOS͖Ih7Oyj+U)HIm#nd65Ʒf7ħX$p4ݔbIE"q"햢Ѩlc k]uj;Ҷ-=,mYXJ&5% 6ɊԪxMg9?$S>_G]O}v*wEUQa8X<)Tʹ%STzڮM?D>S%%mK+1lQQPwk*.)R %S8I4a)46my&ÐTʲI%ꏩ;0R*L7g4dڐP0֏iM[IIrدV<ת6|{Cx)IJTh]UXUPl#=n4ը?ͦl)|aEb<62H*Pp톌fm`0sevg]#QM$% yok8!{}F0:Yo:.bDMvI$!v[)%bE" lNNl )ڧL[B INe2dtL'hL&J . *i׀d%%i(p *X!P"ٶy此ⱨT"Pi=@CYV|*pmXDbRU&ez5 KɒZ]TNV*e!2\73K!+VeURj d:doZj-+[Ǵ/L*iI2$7lojڸ~#SL)RB˼t;h IDATj!~Or|PSuRlelR*X4%Wf@.lݯk=k|ZvZV2DJHB*_L _^:DylTh}0+XۙS9_m,fkCuPVU32kjUnY*V,ozfWjMEHWΞ5Wll+!K>:Xyҹ iÊ%ԯOӧ,puV$--Ҋ+Q7O4W(5dzx'U[U${v YX˿G.O(TUXfVmm[pKdbqKrͧ]^%ZW]$G![v f{'x۷"k֪"\ ˛t)ߙj־Z9Cg¶ζVd$ " Lr\U |,ԸQ^ JJUʰI5ad&M~V(i7J$SY}PUZ5KvO~n:ӣd/+WFS^fLb:\r{|*Lr*.UUԔ7áxy|7URVߝREYp6Qrcj,R %jTUdW m2!? {yUelZiۖz;r-צ`X].l\QfU! ^y}~efvF;U Lw v+PQ`jߩ.lN/uޖ5O ۶]:͊6TLedl%:4Z0??.\=أ@R\r;LjJfM"\ W^umūJy{ivkɤ%Z|jLZlV/bdɒ%oZ_TTa͚5}+? WjUi9 Qa<jCF5є]v)EkkO "`ؽ :%3G9r͙ #adʓ;@CJ8]vV$!ld'ݐgG̐NH -HB ҂$H  -(tðQ,b?me36XdöT=U9 1|-7.o[A.]%e3H  -HB ҂$H  -ۣZb1RQn4M9NyJousFc숟iOBTWWkȐ!  wt(mߨus:vMu?#ҚUFF\.***Yy<IR8no܃]Ӄv1ψ t:m3fƌg>|3g>|34|nrF]o{=5=hc{0:rPAAAa~~~ͷ/\PÇor]wرc4s欭a0ZԴ]#{ykzЮ;F{tR~/**ڰf͚>Փ֑ؾƎCvKB0 vKBH?^t'L EP@wb^H&,!͖ƈ I޼[IC oioŶ5kWJ-1"UŜlh1a֥^#߫$M6)0duaH]T;kGO_üdYJB*[=JΝ&6Ue(D"ຯU Ru#WVnvi2S$߲@iz{M|j鿄݂kyGhxlyZ_9/?*TWZٹTSm9/翤wZ-i-6vtn~._7^ N3ARft@ieeeSOVA]bך5[免ղvAC]!idH:2JJf<'?=9Ld];="%+UuUP5ф ẀCJժlcH:dE[vy~UMmX!/S~+SMJ5,S^nK%ŪuPπS$+TqI\\yJH4SM$`ɔ?~Gq]xKQ4Sgs=-.#U(R8W2aP˦{vؕd}*|LA j팸B;ZS=Wסvl;ZvS$[#G/O| *XVNykU;S]o|ᖖW*Ty:bpE Cwꉯkp^|$mg ʵx+<\'e&Tu^ղMbJHG ˕=V ^^߿E~w.S KQk-5W葚NhLhB51,KV*%ágƞ(J)O*Qh_AƾϗV=#w xK4c=u߃z2u-nnt^r*k~5ZPDoO_WSK~ռ)ާ:x񈺌KXpeګl"__NQw zzjӓԵ17epmŐ3N72[S-טq~s:B/>p{vY]h]_'9zIz~^L#~~~V ʵ-'CQNh#?{L7pY7WW/"o;工{Y]$ ;>,ڲW,=d}v%GAH:wCp}]~nG?;Ы p@̔T?USDH֯WqدJ}(*7VQ6]^Y[gM:-D#SҺ>ix!1t/M?[g^L_vn;if|QGP%YvvX9WovD4WA,U>W7L#$?NJDO^\PS^ٵ/= h>bС¿sϔ6Ji+>Ri/&%Zkl*{Z]Ah>tƹ'6JرhetO T};!Kz[]r?Okʇ_jya,#!lhcA=IsRobIE/E G~^{km$VKJNH-{UNn[3X,x"H4Tj|x'J≤D6OV8xyFT>hݾ>bHǝzV9 9smf KEer:+i6dDN|edڪRw tI.+WO~[+j}Ax>jWKez׸Ul}2]nڎ)0V#Rj_iEy]=N=ZgvnschsThd(4N]lgWٲ.WQFVLD1M既,NrfâDѺLէWx]xNXm B,mzj8( Tk)zgZׯ*l]{lv eZ!$cl0CET[Ӑ[lۭ{ִ.vn Ɇ/$u*+0.=%Y,~z\O=GE72R ^NuoJKitӕlJIS},//š4%Φ'H&}4%n)ɓGml*A#r隻=yt,իYĢ1 fIԛshƂBEu +ҝoT35k22R[/7v;+G.Y4m캯955- ;OeV*9PT]u+zq*?N)Z6}2} @yꞾNO5Ŷ>ةϦ;9k^=UեZ}*?-hԎ`2fO6as`gWտ{]'ܣ׮j=/6Rl$DYJCJe_!4 I]{xj\owp_8h))X)W]'W6b $R\%~b ITT{wFC&D$O ixNClcgW"Oy;Tsߑ{iҡ eDgSvCY74Mn[ВgՠdREaR[<,e.A_xO+ݽ5ieɟ* )X\r&˦ CS)H{/h]F©_]Hl*ԩ'%r-f%dojւUrIYT\w݋1<-fZe%dF;Kݦ?kܦY+_ %UZY4LՍ }?'5s4;A˦P%*h5}׭r㦜l_dnk/rx]ujKm')TwAC;z]PHj咤߮SJ?x%}|[7x]5a_w^Z/k1tӍw/|4c}7Y'R97\7)>c(,qnZrr45~D m͐)K|μZ'jV5bpLs3]%I6 ~ZJGyD+1X*;-nc~ q'?MP+_*s_jٗTo4^I:e IA -V KH3v=[;agS q*0%)Ҡϖqk#}]i:4_~v TμZw*{j~4'{$53S}{:QՔ ;UIزds>Zs2Y2ڨe76p:D麮9qӯJ+STK)} ck?ZCu*won|L>>e!{='O^3+=ScB7O\*R%*MXaEɚ}tm_G?S#h>RSSfԪQ]JJJ\f+al!/TjV2t׫Ux%e2bbN < Ԧ[գ{gr˥fϊOoVJZgJJ4myJKK%u6p굹sGͪccշSRRԣG#NOKK; IDATgϞm'@n$I!q=U): Fg6եYnq>#v;[0EDu/_G~ܫ'uQnnN.^~󝮺"q D6ٰe՚u%2DSC" 7[Ԫ#-5]G0Īs.#΋ڱC܎IRLt+tӣ]3W5p>t4uP?qRvI4K'Ox/ /h4ޑnFc?V g?gowſ-܂?#hښURuAfԪ*e b“Pc`.l@VhjUxPV `=Nz%04!l6^LӔi2MS]6X]6׼5yk^׼5yk^u؋izq5Ǎ;~ د~ ~< SN|?))Iݺu;r WXX14UVV2EDD)b: j 4dGGv`Ϟ=ۖө"Y)H|*--Uqqq $ƍaد`?rDV~~rrr$+::ͨF_c{aZ':GX^-Z 0n|`Z|D Q,AX"E` !%(BKP,AX"E` !%(BKP,AX"E` !hJJ?6 @ӭ[7m/Eɿp;&` !%(BKP,AX"Dp][nּ/:gwJoI1ߠk{u׷sS]e{tVkPa>HQy>.=v=Ӿ/ւ"Dar%^UlR,@cdE0^/?E02Jllx6[#.өFܩG=W^}C+BJiV* 9tq~gcK%*ƖCϼFl{2JeEKL=:Õ߶7@# +B8tٝ4$ӳ[_?3^T(ɡ'TaZ'Z$ɐ9lHR?xS+od(r,-)R}FCOtbC*0w6~>z>9L*ݮOSהG_PU^az)v([7dEv8gm-χm۴]m)&iMUXBV]*ܩ6ŷsksb|+f2ucժ}ӆ7k]:uJS*nJE)^xyM;Qxx^2H=_4yW?.pt`,Mܒg\Wz\r:2˒4/':ʨVh!\OK?.*s%S2BԩsvlE |$ !,hZ4A|4jth G; ~Z4xEvŷ,Hyvt:B3JVvE55cx4AWzj )\+jq+|>I2Agɭ=3%y.r]p uATLɔM}C,${ҖOkǛ퓌ж:G۩X nRi][kއL1vk*Qj5A4-|vM;l]^|@~7ZŴԹCu0\!9j ' +;]nuNZ1=4UΦsWBu$͘0@%5p 3ƊB9۞AW_ǦFJ,;֍zuM/jڈh;; .-gqz܊">m=͕9Sw(T͹;}fc{&/^e?kⳎe>ɧeP:ֹ;w7W 0TX#Sp%™[+t_oԘkYNMR {*#e0 %",g\rɻsǢd^K^-}.0LK54Mn*O|yUxL$rm_~~CnA:}5.5Uخ!fWȑzp@3be7`ngˮ1iIJΙy.U/B4*oױs`ھ' G% yTkpc^ӛo_W,yTk֍]3whWc 9ݭi]*ց)WYHpJ'AWh ?MNz.C{Nr>1iuʉC+(9Pyez18\l_]96oYS)$Z.=G ښ|hq#Qya1U~`ţ1nռq_X8[Z|5a=tkO.77\ Qd"6u{̂ "g`r9]z*$d]p`9RsK0aSǡ5uh2eʦ֭Z*ԓQ2gF*&VuwdCOpjǵgB̊yknהkgK"͚xUN4jq*cX~Oa+YXVdWimLSe+/m׸]:uWmj4C󛙥o^yM_{ ,6o#ra_}ʹ=B͸f,C<34Wۿzݤ/<0BUw.Ð z2J2o ohMFycg혌UNA|!-*ޔ%(JJɨvΈYaS"BVLT;mc.ɪx7$fTYu#bc=:+qˆKO}E֝[^m=dTȼݐut9_{_K2Q W[B}¦Hnn *}^@p˙5=8Hc_:wD>7hm7kg) SWqb됛y~HI]⍯ibi@-TՐ=. Ίxe+_-վSW*nԶMY@$g[v+cy~#F:IL䯜}}vIxhp-/4XؔivFO0BgZ'1w7ة+k? f6Kjܷ~WcܞRjmc}0{U{EsOU;޽۾ѷq?]WK/׍FQ¯`J_0[h{kx>]:hڊ]LgU!rAG/p, 8:\  ddʻB4e-znGOL.8dzu+_i$TB{[߷ I%ڣ1R [ߠ(*uۏg<$2~gj.CF張<“?O - =n?7YwwO#Kݩ ~Z>sH׶~~GضbHxZ%M6M/mT>:J| h*]UIo\g?VQhhN=|up,ld3ʏԠњN:OHHhW$u֭MII9嬒m&|3pr?Իcƌ~]8HMMU\\\xoE|RC@B|MxI͝qϊhJQA{4eϪn*7l@uG;=zqzZZځ={o=Aд~KOZ=|@A_lvum6ޒFjں:"u5'L<١dl׆unx ~һO?ad)cG $Dg=-2S f"@@)frwoQ&!%(BK`jI6M^W65 |&q &b~ c \n_$ICnP ۭz#D q y!w Pt:UTT|>7(--Uqq"""ꝟ8 1 1 r7@*DGG+??_999n ኎n1Xa 564/n "մhMpc r7c,AX"E` !%B݀@R\\,%͞flr1a m7qr7c ?PPXXhuMPa*((Pttt'B qX=X@#fu_(B09*DDDHJJJ^ q b~"Cq 7+3!$\.97@-TVVV|1a 54~1ܬWBH|2 Ci)j0 A$D qX=@#fU۟X"E` <p\T>3Nw-{ァ6i@C,p\0=ZW_-Ў;e49+!Md eggiÏ|,e+ń~+VVjBZ%(s =]nIr(&TYn2| EĵU\o JA_A,S^j<1 w%I>W eDR|O*nCrV˺vpU *\GnWTefmGTyӿ?Ա;_mjKÖTPPRG>3"sU؊X9Z<>XOS9B8yjOUm5.($TqmDɳgM_[LĨu(Vr)RbU"W<2P9匊TDh-qߚ*SmP=Vm"T"ehyF !5B{]**,TIKn-"fhf\ T+jHV%H-<7 ϒ4+B&W?!>owzg,-M\MXou$;[th~ NFG[߼[K?}46M>O_|Z˯#,BT޽Ň-c0!>VfhY} {k<̼T޹KE4/Wnи#uC ;n8so岦eI&ᬱB9kARi~xs=P{.7Nw Pw߮eڽy}J᪊> iZ1+иuO'[Zq -][l?57PΚgF7淦:OfN}1]$y=}/JG#L8.3"趇\8M/Sގci*Խ{w|)SLL233O>T۶m;l٨&is31?KΧRA~J":Am}Jݗ6 &K}.竰%薊=d >e*ԡV-nvn6VB IDATJٞbM=?Cڪ'9Aɚ>\N Lh=:%(yJV-\+4݊!/ ݥEB; ?h?]-T|^|Ӌ6>ZG:KtYqK+~ 4=YWW˴<5Fs/ ScB*IKvTYiȰR]4eX+s@<2 C={oOEϧT%%,s/zŷ.GUFYuM xeNKSvvRo 势D=VLmfXX~SVjLqI o[9G+ۏ[ZroeM蜙רR"DUw*bx}j]kAizvy+U{_?)nX=8J-/QH;:Fo/Ӹ9UG_4ꞑh Z>|kzs-%jѺk=9wJ{Re4jȳԻ\\"ݚ4a+WZJLc ?MU#NweVBq`"""tjZf4h@kWyZvi;Tp|l̒=2JQNCg3~yMEiT4+3&4Q}ʏݙ*SS4W| If$)U{T^SIt(S-3D_|z:w/LSjF*O4"[]By[ǒpC*<Yd.2G{NFܧ zh@PN9QoM]l-3O|v%ch2-I y-{Ys9FsF.FCy#h0:Hf|{yut 9ۜ^cs.~X9  1Z 6u:QSV%9T\trMm-+V5K`{9qZVSO͛yu뭷ot3Rn߮ڵUWO\ciS?-Y7^]Ԧ9]]SY.%<ʃ TehPzsy){IBI!jwszzq^[PkWI< +Y{z`)z&/7 |woY jԺUKzux1ҽ/Cyfbl|7j 5꛱T oTՀI}hon]8ı@5OI#^xLc'kYaD_a=Gyz7ط1CZ@Vy x۶ ڭթSGEFF*u^VC Rɧ)4GtN۫/k7o^y\szC[G+BԱS9J(-N:sDK&yU+dZ;xel{Ӌjjm8.{@93;kvo=u:8UNA|!-*ޔM(JJɨf6EpK/uK\Uy4MmUv&L^%su# r1ffjM} mLWy3^m{^]uwh} / TN3Sj 4i:):s":F۷SYYBةVğnSvEE/mӹg8l]Le9)Z<PQЩdH2z<ү*TrƪUx\[(Ǵ3DӺ)ةbcc%y_߮yDퟨ?}ȥ.& 4 Vj˚JlVCї+V܌T^y+khmoV}2p*b^Mzc:Q]l]M=I#uA RRz]Ϯkaͨ@4t].Dii[2!r1uiBBB'%%[nhJJQ-glm@=‡=`y(3um$*..yckyծ]g^l6|>uYꪫ4}tf+8VdS#GY˖-ƍGp"RC⸱{9ׄ7ԩܩ6*KS M_:.qr 7q8ǻ})))UJKK;gϞ'h)[JB! 7AˤNA;wR^^$-d%''0 v)0T\\3ff6 6OoII#5m]mhq&CR@Ah @%fvmXVSii]>OGy|0dv_#0Ƚ@sw~X ,SƎ`-vːO38Mo U(Bfp^EڟY1ݽfY 3r1PGrKP,AXSAO^W65 |&q &b~ "Dq 7Դ>Qr8rnZn;q &b~ "Dq 7DBTQQJJJ*XO_c㸱{ G?q; WNNBxx<0r7τrp8  SYYY@`"8мEhBa2MMPa ,q &b~ c \n+!%(BKP,AX"D*HOW[Ih1U"$Cqm9Мm C3˔%OLvIUBѭS~j }PG*ES2U[T|X|zQHZRQ\yiTp5c(E9\BDisH%.L#Tp9"jVAZ Zm0U(S^EnwUVJha*!Ǹ sT| 2Q6 ئ,WY.EGɛb0hbԢ44&R?kڂۊwK~BéQrge6qWN)+=_FSt5O y?/Ut@đN5#G}xU1j1i}}ejqf$&)9'%oޤW}9NrK lȃ7|qW+a-jYs=ӆ쫷ԦD^NT_2tP+׭ן}T\K7iԢ6XI?-Ք!ac8E}^+g\M Fךy:zJZ9G7s'I>}Y6O/>×MI?{Zv/ &-[5/]Sc 5sx@=`߼Cܕ{_ZC_lJq%.V%4cyLפ+1TO{+ l{]}-+޵V,{Sffk[$G?C; ?h?8cU3i5kß7Iy:Nk/tM/jڈh;; .-gqzJL7+-)$l6˖mHjO=;ˢT $5whCtq_^~P=tV] wRW?C6"趇\8M/Sގk(]J޼Dͷ>oҹ!UO3jWܿި1/քϳdF_{~UG>a>q4C!7%瀉>qK+:6{2*MOꕻ2-O ÔQS%iIZݎ3 6Bo˲}Oː;V!1'́Xڀ:C+mʵqn|3Wo^yM_{ ,Z4Cuȿ=)0-{fe=ZM d+;O 噑_ޝGQl97!HAEEQTxв1.YLՊt:9B_CZM:kuïm E l) *X_Ϋ,JM?,Д~%stj-GS-ˡu i]yIKW-q'+ur]Q .ZpzghrY-u5'*erˮm}zvR?ܫuۢ^d>T%K}ma3j}5\'4\ۖmK_[V'>ІgoPۧ/U_3Oe 8R\׫ů]S'A{sʐu=!ד5/m$b8O_iF1-_i؅Wi/k`fOySϛst;R%o$;AGQW,ІzGm{h׵5m|k2ߪ{~M^?k/꓍u]cuZ3Kmsj_'4\= a`ʔdU%/m=L~j=1>,kymDyeu?2Һ2RR0C.[mj-\?qB=Mpsl*^t!/Vv9FF ՃD)wݏpia)s5wF]ӻVͯuRh,ݢK?+gk{hm_DGu:}Owj5c0jUV= ӨڟڒͨvuBڻn4LdH@[פ3ݻ礥u ի;:9Pn S_ [&k]g@UjjjЏ#|k4h[>EI=fOQ\Jlڪ,Su&x\ݦߠ;ym8vgee_~.۞ݥ! mS7ȎT׳)m @Oև~ f4\:zԻZ~uf<8F/iO&L//mcd(кBEkْp@C@C;ޭ1dWj熖@HR{>mHrɐm !@D)WN*儻]WkW3 !p!p!pdBLL4e5oҏDZcm c7D$np7@bbb]~ D&05h[ BHWyy***dYV@UWn|>y^5>,akn?ж0v@b:jG%%%*** wSTic Ї@ Dnp7/D?Z60- c7h 1GBGBGBGBGBGBGBJwo IDATGBGBGBGBGBGBGBGBGBGBGBGBGBGBGBGD->L7\7H M$"R !̎u7tWm+]ZwU4/SuZ:Z#N~4+n˄ԣŅFʱ:ӵςߍ^zj%h?ou@B=lmPNY;tVZ[}.и*Z{݊[]:*1x2GRj:cԭ[,-rVj?VG>Rt>LFI_]puk'H[~Z_: h!Ժi}P*ѽû*w]VitvK2E'q'hQ酫z)؝,غa|}zmH2;;;GPY+}2=̍1Z5[ Rʦ5im0 w\@`C9wd>}k]Cy\ːP~& )wOZYRT3+)n4 []XY;~\S:FK~G9V{L< RSOPE$j0`ӹ^p:%vY\5Ѻy6Y{m#VhZnaQꤚlYeل4 h˶|dU6|>C?U''wUVa#u%j׆5y6?Zl! h7;nׄ@H )sxMF;,E{V4=k&+OкBé Ҭ0{10w>)-*Rs:zFFzfee@YYYׯ_gggwil;-N!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#x^~YЪ)ۭp7r "gϞn RNNJKKxЊBz9Jqqq?l<D/fĨ2wBcY Ðmn a<{ 8;!#!#!#!#!#!#!#-DTy;}JQ$BDCZܪTqnʬe+Z1 $%%P@i&㚽37L.}-+)"M\̕\B?Ο K (`…;!dzIS)> B=0ޣ&haeP"pԂyҷ.7YSO9@[B࠳BvHbUؖlcBl~"_v>Z3uei^Њ1HG%%%*** wShbccx B&_#!#!#!#!#!#!#݀HzeYV@bn>f @d9б% VVV&ǣ={)J999*--i8ܱ PՕQQQQ@'Is}pc39csK3!$~p7V/&&F @diܒp'$˲dlwSh hҌD- wBGBGBGBG`j5=ctuI{in;!ȶm[nѠAӵaFh!H:w,4TXXe?.SIqIT-9/!]>UDz|YLjW)U=]|ڡtƑ niڵޭ :EKt\ SQ1KHTbJ}1\ъM')A!z䫇{ @$UZZ.?(K.EcIRQ>%tZڅ+V$hӥhwԏ n:*-)ԭ40t]GeSl`ppBhlUeo6T_ea0]rM[EٶK5oޮ0Ȳ;0 C'xnݪxC|KvӦWSEԂyWA~M_y~UYzp־|r5A:-˹PnYQ͜%eQ2l#.ѣw]AGzTKQ1:Ծx^x-7cvc!n1v卝G׼߶4;+Yǿt+m ZC҉eoUfvqS: @g۶ԣZh53ꫯgEvF]sgj3uI;kB  !Ua[mrUDNި"Q:5 ߿| z虛ggzcZ 5{A=_lP鯆h̟UԛjӬ-7ViQO|ʪkG_Z+$CVet5']^uNנiڴkͺ5 nk;R[q d(1? EQɇˆyzeO{zrIʽ>1*< =ql_t}zsk<_zvƒ8l|^^۵Q+[S^rv3V[hWe*|ozg],c2"tԍ<`Li:ۡݻ)!!Ai;i>t~߷?J" S*5iDiז (I陳k뚯ܳS+YT6~]qf_NX=JQRΩU5mA~^9Y͜,# *]?깮nd˔i~]s7lIXdK۾~Q//9\~[7)LpB5VpE|IvH`C) \2 mqb1r\RrR;u]3_}z(Ee/Rb-jgilj|ٖBb8Gv*вW~_R?GG̊~zd(]eV Uv=Zer;HVi{PRԔ>UsRc;ۯG._)9DA BGU_alkVV-me)*Q14V߾"^[mNյ= OjpZkC ryv' :ʰZۇP+8"oo™!ROk;jFm-Ta'_Hk6U#tݨ/hKRzoD)/SH!DczmkIzo !}Yszs|=B)S 6rnZl,%34鲻/˔)5|uQ @tQ=,uM))ZJ[͛o+/7WR1cԷw/k Ug-~a*׬ST{#nй[XvbyڣcM]7x)"-K>^媨eYneY|zkt}f @diܒ0S5ǣ)Jx;9QJKТ.UgS+1y8B7T&^$O}~N YG`\-r#A@eicO/ӥ:īueKVH_^zHZVzh7Z}.?&Qٟ,І3I^-~OtiX24BM2eTj9BrlYzXJŒ$Vv9FF ՃD)wݏpiag;jw{_mМ[t1Zgڿdj5rNT 4MkR]߽{^z5{YYY>6*===MUjjjrgee_~.۞ݥ0*p!p!p!p!p!p!pDT/4 d\/$ IDAT,bv+z@@111nh!@ĉWyy***dYV@cY|>^Њ1HG%%%*** wShbccx B&_#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#!#݀x^~Ymir݊oܚ="6(++QϞ=Qii<OQԚ="2zJLLTLL͉$UTTy_@4fB~%''˶p7hn=n«=D䃩-˒iFd64@Wc5{$8""c0LvYn@;v$ In%uTbƷU+W$CqJە*-Y)F3Ǝ@[B~Q7 u;~e@ `rǻYǧ9ua 퇆ioWD΂GzD#LՌ KUdu쐨蚚ߖ8OV;uN-JKU6厉U|b(8֖Te2<>RIn;ЈWD v̕Nq `GvGhˋt 7ows>i֕{ZǩiJ׮LqJL(v=EݮVQRShZ^i=UO!Vo,_̺Qo_[\m޸I[vGxOkܸ'jв)QZmjٔn;}34oR- }_=|:U{c5]vT ߸VRz;>uZPxG)1M\,TYq+2INR|!Y^vJ dx+%He?]jBSZt;E  +7ʖ7=WɗuwwUV_=(8{|;tdi묗4u='vYՉ\.qe+oP]NUaP*ܞ-՜H4h]2uX>Eo/(8D=OTbӣީw6TK^ak(u;Jڶ`Vϭsj]f۲/ռy$IFsT [I}{sl=dFyvLF,qz#<ܾIe)= 6B+uZv e苿US{>F?c}>bl?I!_Rn] oU(j{:\[d?Rk|^7^?Fߺm?^MwBs =*27Nd0]r73םWߪf߯gޢˏWz[apugZ?; p%\=Naa˷#S mRȶ4;+Yǿt+mVB6Qvh ctQݽZ7*m=M:;WoL_n]azٛu\LDsCg]н(} _x+4SgrNhߛNq55z[i%*J!:Pu~zG5`@ pN8ru?ʻZlw͞7Uֱ y m6mɲ%Kmmߥd:NfK}6W~lfC^֖WR@wB68xln$-{vsI$>pFzZoMKqCQkPz[j):u)ni}JoDye{ vJk/W|5 8tH-oNuMuNBX8m%u|OzK饷Ҷ`~ƛn#{+OdФwO[GsԔTV{"=r;>ˏLih-ՋW<σm8BsQj(IUκ`ݵ u{G۩B@PYY+S:*ʻV+ mIXֹKuGtZo{-{/ m75.F4@{zsi!ˊjm V(%Y*Qκ/ՖWgЎ۟Էeq6,_mmFxd+˯p?l3I2E^v&dBR]IҝcF֮ErIUW4lzxvyyJPv֦ĄY :{8>Yj:S+4ӊ׃;hԈzo2Q<2Y.-:mw2#$zR͙*)Iݭyka6ᒰIwim8r{G볗>膻/Q_(wߢ֣*5iL޽{NZZZ}_P^ӬWXXfo!T_ъ2Pyzf)tG .s'9Z?Fq:(ζ*T` 3W7wr>Q=Wx޺RUM 77Wu.nВP;i| R7~ջMKc;F9̿RO^WqqqGGSkHwBHQII?d2)"(bGEbe˺.]+ؖ'+@pYq)REe]qUR#A]Kz2$I2 B*`#G2s{uWDDDDDÁs?vШof-BLJ """""RvIX>IDDDDDDDDDDDN*BI"*BI"@m^/>0Bjbۉ"""""։fP "tҶmPwEDDDDIOOY~"""""QjaYzE~~~#""""DGGPRRrEDDDDB>=e󑐐iHeq5hEDDDDBraj0Zòk""""" juvЪ+DDDDDDDDDDDPBDDDDDDDDDDDN\BDDN,>; gWA_1EEŔ؈G'6ҏ;3O?-(G,Xǔk?(SGkD$QNS#,14n3>P2ˎ"wQKЭrVb"o?CfєdvI qʈmzlfz*Ir>P}mǙ}E%|c*m,ǷpGhWU/^]>=P񺍶OeIL=8Wu0 kx&n./1HRBDA2\Gi9vSMxqF"D_Ca.zw70k]!e7_ۈ߮y"" "" \E157<}uWnga!.|!~G}OQ\ީ=[x};:* LJwU |ZnņeӌF';[q&%YZ ,V6 dDDDDtgR='6/?Iۦ֟[]>?zܑ n,ߕ%H+^SZYDR 5M̌-|UQP~~ {|C-O3`CF*!B48ītk>gʯIEVJ0 R^; \yVzi}f)1 Lsu}h#,8;бc:vlO6N#""""r"2Hˎʋ<-if KtR}ngY֓k?gTfrCg-O%*DD/lgBf#f[IוƧn[oz9;*ǘ Csn xac2sgBL 1[h6bK\r-gUvOm9p~- 9ٔED~ 6{==tou( Uϫ94)Ioꕡ>wqN"|{⯺y,4o=:dVLŠmBDDNBN_XF^v/ȥ3ĞM-[s9uusc`d7b0M/7k_Tr_JY˙W}= o ҾĔgw{),O0z|' `bj<68\00cjG~HC"Hbŷl?}*~ڪ}{]ʍ4b, =Hw"<~+l],991 9'r'5p>u߃偛x"v"`Hb*2 @n ZBDDDDNw$ ٷ;lێb[(Jrgs4gӏMdvO4C\҈#a`4k;@ >a_M/bYs?19]!"Ґ6މyyy ʖO[{4!1\<?]QPqQ1>;㐫31n7Xzs6ǼUzxg\e2q6o˅ν!~m GlqqpeH[wsL2Vn%LT5Wep*w~'O ϱݟŎnf,#s]2tʼlzM>k7_ >(9 !"ҐLkY|!F~l;qJwGeQ|Ux;1^1o+`Vs?U=xd>#\=Ov%Jc׆ lV=2ށGBi<붾}nbJ)K6|&>R73d'x|Hm/C[1mZ72oh}{{ }l|tQ䍲̚1Z5YD}֭ӓW}=55?Ok׮Zs\4k_Vff&IIInSn 2;}=.geee4!^M},%?#o ԌhEDDD0%4)׃ebiԔh[}S ``#E3XK1Y96=JW|< #i2ܙx*aE n?C8F=x'1udz wfdDDEW|DD,͸s~51 ?I{/};aƽvk<ԾPrva-l݋W/Ǽxtim՛ƕ,`Y\QSm˶cp Y|v^ $UW6cJU,8\/Xv _Smk|""룙""Rf6K'7=Y?6G:Pj/ʦ.}y^.K^@ (.Ԟ->ZmG"G]_߳fdW %2ܵ) k˷dj^'7XXmD9WMtݴ{G$""zUS*.gѤi-hAK@bٴd^#)`{|n}׋ \D31NL|WT|VM?~{70C }93'yYiz:&p{ M3bچҊVZu̸nGmFρ)`㼇cC*Io@oD2MS7-4a[peCg{Т8o;jj/^:pEu/`XbϦvY&Vʹ~aҲk co P_0Yl ߬}TִA,|nw/坅 F""r<!DD䄘 ZȼCe,[0qIQ;q$8lu7(""""ҠRsuߊ=2ofzG BZ(-ZG]!f Xi4 v""C.3mQ>LJrgs4gӏM}u[V$"k"ԟiӌf FLԕ15"""""RvjCs>ʈ9JCƍ~/vtч1 cu#HT!R&D GK#F!wLNίc9#XBtӋsrEC;6>9}!""p#)3Byg<ڏ{{,ViӝN"""""XX-`VEU]ˢʫpwc,x3ؽbZM FڷIn `G`,5 ꮈ4Xv]F]DDDD$ ,6 5,&""""`XZyPn 2{8ЈADDDDDDDDDDDN|F /yD4I&n uoDDDDDN/A/\FMHzbik )Φ`'! N+A&ef$EZiGDD~ wf.YzkQ;iY}.'XL^v!Fg{F" {qV% *B4$?X4{ 95L~T>THe?- ?vD^\iX;o Vy5締Łm1ug """"RQ~ɟHw%0C߯3b!tgr`~ sO eidWu0 kx&n.7,-#֧qߍ\vVy/{+9Tip ~|3VԆ/BcYS\FQQ%~{d(.,SðDp6"Je\J$%x8]u~e@tnθ^2Y mnBQa 7#d;ִS0ȯxd;ivVkZ'G`)6 PDvv)1M+dq3fy,.,YF{t[Kd ΄xb"-rՔ_;*-e7_ۈǪAκo<=~ᒃxcZr57)y^[ 72~/q7 gbJEUػQX ;s I{q6L{'--d? +#*BFTipLrgYF\3i?=$DsS^fOӏM ۛ/lFl KKpkL4<ڕWwUdj,V6;{ VJ3oKs+S􉉈Ԩ<|2Pjy C$όO÷?|K;F #׶qRU +nG՝8>:ӈ`V* ;3y/=wu I<̀ }OWjr7}la<3m釋aky _*Ƿn>b:f (@80̾R})n_>M]\0',* ZGD2EdÕ7'xh[L [ 6f>ZA9=Iyfq_L5q,YAꏹGYA_7ſ3Qʹr ryt؁ӾM#Rؙ'^EV]\FЄ.7UmSBDDDDB 7>f?2˳vOzAYd:oc'P`GfBOrIR&ȿ6sW"`djτgTfrCg-OI_G}JaLc'^F玑մm!Gymp\|{c˦&jIȀY>[ aZZHDqCd;Dao\L? y70vwsc;hgj,;4}C.`1uS&sHyxN }Ҫ`u;o4zOǯ0{?wƀfH>/3-–=•k""A]D6MhDdЅ<:~ |ד?ffYG5Iz;|i.6%7^ȹ$tε {xo;,%rj; Ԑ+}Gylct|# !+*k& pi9X12%uc/`f-b{TY+3|#y{E9Yۏ~r"e`_Fᑿ'.8+N2" Vb/9HV~u1AKυGjWm{ F.%l:}?﯌oigv&4oot> y"gТesʈ%DZgmEмytWdLJM[x!f "_cjG~e EhLP!]9-dς}<0͗h"-G<(o?}>Ё7,bڝDD47"" i [w4n{ W<69og{ܒ,LBBo)$Q/ +wxaG7fIK3X;7wi C 3?(G @ E))-,fdfqm.M_Ykny&J|>Jur7wхiYe_l [PM0 SVmF[p6El e~?Exrӭ|MpCw:wm ?ܘx2kVvΦ.&PWVݮ")gkm,\Ǹf=VU%*|ˆȯfB48peH[wsL2Vn$:"l^8۟"g{=Jƻp5n%ϞV}{g3zz2>#=@%0fmwW˩9:&Vqv|C2bμ;;Đq#7*F=<3dq8B^ޝj'j$f'L{<2:pF\Kr=FKM:6ؖ^x?< E.:4PIzS=Y, ?XΏf5dx֛|n$A07>b'1#%vь;u,6A7G>3Ly,p귈.TiPXa~(0/Od[_s n>SFۢCwcY=3f\  'LO6{e` +l6Ce\Wy!}Ell,F}89@ g[^W^Ecj?̇yɮZ}x\iڐAO/!g@XFZ-`9-;I'~_F} LV}9~Nn'b,Ч1*jwuSʶ3k\?jhӇ2< v#\k >fBy7t^ǘ0j\G2[X-`GMHкuU_OMM?ڵ\.͚5;vEDDDD䗕IRRR۔EDœjRf9K{sD7mBi{;I; uWDDDDD Պn'&&^+Z'C)lI۶mC'=="Ng)F}3{eGTTH @IIɑ߫Rn dpEGBBi+""""" nv8Qn 2{8˅ j ˮ4VuEDDDDB4b",$""""""" ^2 hLA/\FMH^ҪOQv6~; gw^!2)+$,D'5#)Z܊}+A_1ydfEN^>!9׿ wFii?Y ) y""""bftjȵ5gj )#;3 2s/*8sf|2gb^T^T9Nμd;;w~o#9<=ǃmsg_J _1C^~%Rf Ǭ28O(' W |b22p89e#;v~Ν_35~N""*BOnǼŬ޴7dL,2K~iq7vlg,3EV bk>x-*jU5|"/æ|_md^of \1ݙطsepƐ2s9c|F,-OE|y V/`ތy8e"|n#tz>zVFWT60b6E#E 1o:Ӛ5S0`[si "Nv""ˉu8R.'{|f˃V9 EcqLSAfZQMqZ(**ObvCqv|x⣃Ƿary8]ug瓘6\OOx˚P|B"""""9S[<0$f$,zg>Y8՚b c f}Ԓ᣸Oوc0(sWj')ю ܱ|ATk-ѿzF=r}ypӒ FOkj`4) ,WcZ6Yk ~^ݹ߱k|POݻgr_;iqh!CW\ t78R("HؽǿZC,L-#DŊя0>N^|Wۜ2w.b+3zV. %""mǵjü=6 _aȻ8O&e߳q~aRmjaA$""""ᦶL},3oKs+*-:0w]dOxK=Āfrٽt/::&{<.9o}5v!sW'Ȟ-ߐt ЇQJ &wv>3vRV.ѯ'~իW 13aWT V(Jeʽ]`ڈY`tfp)>/ʦ.}y^.K^κߔ$"^; \y^My䭝x{k-k3xg<}3ч4^6{6||aT; FZv W^ܜlISBDDDDQm=D>V}D]Lu ~}0]l[ıLxg?)tiupQ;#Xk xLez+7}T}R.zk>y4-L~etYMb׆  ʷ;;бc:vlO65X6=6WH@<ZVyDD$܄Lԅ&S$W꽟wc[3`>cJ \IwO|ћ)G:F]؎U  3c~I)"lǷc)ϩO6{= {! > "МHQn4JFTl IDAT]6\r j 5ccMwsc;hgj,;4}C.`1uS&5dJ>32[34"2•w|i9X12%sUv3mFρf"׉Oજ2s=ʧ0xIDDB*l""r*yٽt#{6゚^WƷwġ6Itzb(Ҏt!#?Ё7,b'998&!XZ2wlHlBΉ0s G=ynI&2Cj@wn.f@ @;|Ahqzz"""""iG~YG>zkfW֚[82~R/%~é40[ 14q J)>eo ٓ>?f6_M\YnL,ٰf\ܩ;ݯ(eT} <*_0|gҡcqQ(8~HQBDˢʫpwc,x3ؽbZM |̥~Ϩq% >SFۢCwcY˧YlX`Ua<K\l,F +V}nbJ)K6jψdY̮eTï90L}L>pR2{'kqkC+Xf|O-8{g̸_;8Ol,dl,Zʋwa+b57Vy\Y?撿VkEl>9OPy?_fW57'mVs/c5.󣋰&He-VX5=ZDtR=[nܼ멩'|]vzYf'ܮ233IJJvri~5)^9{6!Mդ̝Eq;L̻z`4(evz|m]ve5n8x`њ"""""""" yǶoµPwg甍<ߜaj""r un |,YF%26,xs4 BD$̄ejbV&jJ]\]DtULjjiN<Eݎ#***]i"""""u:,P\\LII a;""""" azq?vШofa9tRXXH~~~"""""8Ng)F}3{m >>>]:(HMqL"""""""""""rSBDDDDDDDDDDDN !DDDDDDDDDDDPBDDDDDDDDDDDN !DDDDDDDDDDD䤈ujz|ꮈ4VNLLLWn9N4R!<Nmۆ+""""" Nzz:EEE8ZSn fP "%..(C'::#W."""": ,>L uWDDDDD,ݎq@.""""Zuep S]i0Vk<(V]=h """""""""""'EX>IDDNK^f!MI[ ŕ֨ Q5ԥS'?E$$AiƤ bԌhEDDD'6ePLX/sNez[WD$e3HK$;ύt:]WLA^6gdW@vfOAٙgK~QY}m5{8hߗ9+!1uw%ٹv~篵y9<6$=/b5#3"J5L-4pg V: r=~̪|J ?E9dJVn3XL^F=ldoعk<ޢIDDDDNsʚԔO8;Cm;Ғ-|r/w2T !zVFWl+l]p fQyi͚C0-ֹ誈ȯZ\Y7ezeDD~} -̬5D5]{r9K3k^$M(*;x`HH&>{5+Y||q4?5-ǜ1x#}tj᣸Oو*},sWj')ю٘iܱn"[v<;?wL&쐍+]RjkݭKVZת~ժůRת*(TЪUŅgIf 2$!̽so>̜9{QjCCmKCOK>g?VR;sN źvvg=Z{Jϼ[󶚽ֺԂ5wǕ?Ӆ/eIک `}Z W=h:ت/7_^+HGHxZ+ _ltȉMFq:+pC%3miy{i2s1%< *0M,g87]"˱5s^v8KﴻC랻{OnZN8]rJNAl7N[׏Uݧa%eww,SNE Ou_*^c.y|ksXYSoZM^.e-o^w<^qԝ5x\%^~5?뼳ՁoI6pvRW,ͮ/+(8Gok!t2?U5j}x-'5w%K{}ܨD|p vhތt۽UНUq4Cܝu38:MqWͺ$9ԏV@ن#ҟ9TZʊǘ3fƌ]_ TP3&=˯eG [Gmsob?vgJDS('P]{oO==qD==;ϺE7_YS:#tkt]=~_'mNaOk{E:Wؕ)m_?6S_m#!y 4.p4ID˗>/zjAJւtud<~.{t}>zdҫZlgue]*--7TFFgYQtp|={$HzGdT/ɭnvr{~?씣'uOn?:Lժ֘\__1A555@tPZެ"s*:PN秺iZcjUsܪ)$슗4_fj~S=kQu8_ plo9{IRT_M'$wFz ʚ_;'IoΕg$>vJZuk<ۊ}_w>WZ$.(x훿POO|BӚ%}V=Ek_KSb]ΥMȸ>7&ꁏԋSzbYSRT OM';Ygҫ &G,weyJT^n^ڌnnUU7Vƶ 5}RLeC霶_9[WtVe.PI#g~|C7,-򴖍>I5]tΖX}Gw ^V{}>=eFzM`m$ɑIP20=(':_ +ۚN/KJ{ܸvHI*v$*([ssVgz1jOotLg85fLϖYBlɊw*Q,Pmf{=]ϼT( T t@Ψɤ^8n/5w?Onu;oxTgD{ybJ5R*Vz?kxg2DZJVKk76QOGmẻ)J)3T\#+ب:[rL*J)V{6@*Vc0 INYyzԃu!Cя~4^Wd[#!q4A=s=:K4aZ|f}bSnjel}Fݩ}Y=n9J=?#qpuӥKuQ#d~~A7O#u'O|~O֜Z,}Qk?ӛpM5O2`øfW}+t-Ou ׎rcW;TRoVm3=4 Wu.t:yzx7:j~m}q¹:zw8F'ӇP,6V{Dl,WhK/Iuo/O8['\w:_\Qjt51C7:K47ӘQf?7kw>S_96= HB@`ʔ`_Msι8FEKNBh[9Qw="kԷ\N/r~rXI5oVZ_Gݔ~3%S\.Cgt~3wBNI g4hʢت}Y']tcɑ[cƯtRs=z'jiv_ki)\հziZ>מ[L[;e7=xʇ S!kU)Sn5KK_LuWKVFۯj_,eJiinů5^]7^E5z7-(ix`{]~IOKiiZ /jwer莛t G)G5-WfjZnrKaT]]]WZZZsȑ#7q`Peee].~~v7\~v5>Jwvj`p7AEEEFQ_X]tƎmݺX_SSSrX2 v8i}a_ooW{/?]G2d=mz'ئiʶm&9w_kY$Լh#y1(%Cu<1`@Tv;lh@}2 zL&Ulv5GmK檭dSmrMEhW$Q,m۽]`@m[x\hTG=m}r$$utt\5|>MG=m>ޮM;}r:&AdI$!@F{FL&evoW0LӔl"+hĈ]`Sgg@oW@?'hTR[[[oWp%IXld"L*??_vU* Ʌmۖiɪi{dIؖQ5(܂m̔:9MkB$jhQxKor{[Ɉ:;#'ӲǛ% O#ӳOMNlC7Q0:U_)E5xRk+Q/Gy׺UiJz_:H|9"ሢҶd=(/W Xu#*./B0wuJv M{/zdVH^]dJ.E'v .^x@-Kؒ6vu{e+ jWo{ЛMySѥueVo' ]s3B>[ѶF-U=xJ,M9z+bt$jgܯGm;L;NÍr.TO-ZX~PӴ Ra+QgGVMTKcR[|zeJr"!Ei9.|2ҝjj?kĀW[}2nP8ԡH’Hප _<=Ɗi2s1%< *0 0{ue׸^/=FPWwkVBT<]}M|5gűNZGޤ{/[kOdʇVŠXuOĶ` }x\%[3kλE+Ǻ'׵}Jr4y5ۡy3mWAwJVőtrw.'/O|#4]5ti)dMzRB~n52nD;;<=ڑ_wRydnء:Biרugi֛ #Rη/GꢽjOs}hrPr OqiJ %6 S@;U|b>tW&kÐԢo3tPljU(ƺM^}.9PNΡj{z➉zzvRun7&ꁏԋSzbYuE`d4}a:ณu*C^չP20=(':_ MN/KJ{<.έ"*'TڑdD^oy~YyӇ=땺[,I*^;O+jQ7o?=QIv: t_芕;DfhvGXD%nZZ셺]1 }X7hZ+ċo'5fŠw*2JӌGn݋f۲[:eTS-#UqQ`J9rm&JYkvwزmK-aف2U,Dze$GP<=}湚\KiClW-,*Z\gO8R?/$j.8cW|X^{#}{:C̕۔l+Uc)N!%V98j9%0z=zbߥμ]gk֗_-Vm0!=uhZfݖsuu+'pN-'kYlɉ:X04_)KSE<5JgprQ™}eu&)+G99s|k05׾Wk=T-R{35{o5Z{?E=̵t''UT8\f+e\oMI9z+*Q]]]WZZZsȑ#7q`Peee].-AEEE] Ѧ7vnMH6I}2 aljm2>@?'zJ&mrW|+(1"lV<W4UvvvoW@?'GBHR PGGz*z>ޮtL# 2$ #HB 2['7o^ol9rdolEL2$ #HB 2$ #HB 2$ #HB 2$ #HB 2$ #HB 2$ #HB 2$ #HB 2$ #HB 2½5NFL&e884z78[w &hԨQzZ2Է~)Slq)&}18E@? N|8>2 1bDORWWNO7lnWvmgfj5yO7Q)q`s2zSuuu]iiiϙ3G#Gh4*/=|7XLx\ݏ8Eoi}:jD;l) 8E_G? NS=yivv{ccc}MMMŦΕ5!$ÈkH$6q89r&@|>5jM):bq8E@?in ɶm!q2y` )zSO437rz%NћSu(q8E8r$!@FAdI$!@F lkdDœir͒?=mA%Twmr 5(lwnr{\w,+(O*mK-ϯ@:dU\^(Vl5$WcUJb'Cm15lx,;Rbɷt6O(݋`# 9ɔ*]N_#+ D\>O&Y';_]ޥk~V;VκD qdh^/x`}rIaywx5RRU|=ި_5ԋ֊? N><] ]]N m;>ɥWV\PVV$3WCF U^F,lĩ$+`{J5:ZvUA@ ׅLUcgE:)ձzl*N oQ* =21mbts2MGŪ[5V:nDn.Sa^d)T%L+8o38 NR5ԹF` +(ͽt3*VH-KY*Bo~G .!K{쿻C랻{O^NRV1~IYs4? :-UޫO[[N?t'Sj[>OQO}>0Ik:C5bv7sLߛx\%$W5tU'뼣gſ[]NJ X֢Ȑa^PaY閷cr* cUUەiHQBr[!"K⩇x!ryۇu߿R㒤[]6!_'=thZ#$sΖaԼ8]%/% E{1:6:x4|~0$H{)pU q|Yx\2LS^_)%XP}SG{lկHRnhyg O,[SQ̕!庂j3}P u.kS7Q1FV(U?__rjv-ׂ$u([T8eq˕$suN#M<=}湚\KiCl\nC2$9tZLr hAg+Nӥ~sT޾^fҁĖ8R,ǖ+GGjt'jY\O;Gt5%zɶk YaxguA;3/X!ߠJeT7o"ô}YJ#-RGK6t{m]YTZ+KZÊLwmrk(!%'Tx_|鐂e*(Q˧D{67VyVuUT s=8TFCUPU:y `TR^ Аud+Fb}aVmd;hTq(gJ5bӱeF>ŐX9v- 1WCނ8- e9nVmS~PY]A}I-ƥμ]gk֗_-Vm0!=uhZfqq^Ǧiƌ4ZlwnR;ZЦO>DHi@iJ!SV0zLL_w;HGwriҳ{_^ɓhꌏãauS]`YՆ;TRtxT>t^&t'9[j?كTUhB&mV U^5X6Meny~y7Z^MU*,9"WWyijU{^(*YZbq }r-k#$ڨȞ{iU7mׂ7'ꮇQ8)q_}μ((3UL-'_֮TcyZM,TtO:Tا"-˔r-#YɈZNV,)e ̸ڛ'(qF9z+۔)\szޗO\o0ӯA4q'vPUEXT]Æ$S$'Z:EnUThȰ"%cМۖ-2UQ9HCIDVX 6+,TQ2MmpiiW#ʪ4$ֳl$][Y%**stҊ구)N<>VRIWUǰGԲAMc>%%rWJRV;7:-e(PMp ÁkђKK4-J)٬E-bY$O֭s^mm&<]"T]{Vۏf׏c1Qϛu_Oxnpկ-KeCǧZp[V-[Ъedz*INM TUw,ljb1ώbM`jm>Z/溋dGt4ne&+Tݒz"X1,[6,G$ Osh?!  JbI[0HyvH5O@`!N}8O X_0K/YڈSu(q8E87ovmn766TlǖJB/ #HB 2$ #HB 2$ #HB 2½5NFL&e8aioq} |7We53z0Ip8@ #FdT ٩@ У |?We53v?`FhTR[[[&O$;;[Vb6m'U}͌5!ɤ^o&O*++KDbl;?2 kfl~m[aqLa=׍<=`AɖAUfp_3ckft$HB 2$Ȉ.L%\TdG鬳Β gg~U#0B7A99kZ;JxIDATZhfPK/& 8|,]pcѺiѢŬx,9J‚)h34{ێ~r`U~:::dFoWkQ6t]R|U%,WAL_= (ye#U4|:&x:eFت:C!\م*.u^ eY),+t:-q ?Q/[tZioWIWWuUwo}'*++WsqN:H8h<-n d}mA%Tn%CӳOMN$jhQ,D [ÊPAYc7ʽz٫t?՟ǧɈ:;#%r Y>sstr'wdZ\x)ǻz|8YfS)҆]YwʳYMGPZ#Q +~5\erFe˪>F7t0,G/u׽E֖֑J%im˲jjiԨQ;ǩUuU_}k.y ߃>|4Mٶ@)˛:Hnjь7fl8;w_蚳&h*ي5jg_Ղý~e]_+.m{g]|qξfBkƞmk/㥗.P 8'Ԡ9үVMucJنl+wk (5+]HD=N8{o:i - *`Ŷkª "(+]]T@D (HQz1$ L I 뜜ܙ>Iyk Ԫwpf~‰Pm %88ˍjŨq Z}L934"4Dvy1!|z:OA0 Zؚx>co 2O搝Sf8#y+ũ;Ⱥ`<\]yv]-lg}ۇ@/$Ӱxj&oMIiѫ Nf}vּfdtefwRey3W>1:DJҩb,< \ʶC:Adn6}F_=m0mٜ^δ5Æ@/iAmk*WHkRƶ)O q܀h c[{0Ͱo8Nsev{'#*/̈`o~G2;lq+FW2ug8=k: jy(~'4qԦ统BdsGc/nКZiۘ4q.-xZ .1O (&O^wS};W_,?wL\mc要1yM]umg"Yӣc ts&%RoVw(wy>Z 5!G鮪|yYLria\y+tbj' #Ikt?" saqF_<X 30hҨ)KCf>1>I1fuL 7|ЋȖwngVVՃMLJ#[yfbcciۦ 3g"6Oa.L]㎻hP~xmKISlseC!g cL(!ȋ=X5m&N8q:#vFmbxj<יQ 婕|0~2wNb#-o\ogo.{dn/VV~Itğ\'| 1K`S!=Fgb/?ˍY$(jp[{"}=ie[I nEǛR43bnc7w 7cp4?6}9ܑ|\\fiyUr\y1oµۈKKE Á#/4M7fAf szE) : _'\ uM`ޱįBfBl6l6>E@Pd8<iB7:7]uVy("(nO>$7mǵ~qmX(ۍŋb߁}m%$&N;BLӃ{;a6ߦkh8>] g`;MNo#07e?Npl"}v.c| V(PI`gS$3?[8#rG[>(_@xi|tw3#zon$3+<nglH[$,7 V0yel/񹗛} &i¯]NJTrM !v93%<`٪ TDDDDDDD4S3 յHKK#  zLbY0};ȱeײ2ٻC>IĖ/pڷu⩦1b) $o$ѨAϹi*ovu`l 9r0k^o7!5פ 3bp:  L$|_/;u=ŞgQ;as@c#yx48\¹\3vLܔ(VNyO8 uyWQ21LuM#))G5uiy'}"'Avr x2 w\NQ0Q76Y(XLPB:FZZξk 41,VA8y/c==UYA =tp~bYI4  %i28McI.cyr8zZ[pV]m v-3|FL[gA:1'ݔkqlԫ_$itCH^͚py^fq`lƬא_^bb]o&$'""""""""/ mVXfxէ`4k m+Uѳ&Œ_ɯK٬XJY8tfW߉w`:|̉ؕU%')' u cNrRY% kS`bqsdziyx~p2E#V+- ~9d'.F Ia Ӷ6zr`%sn!jYT&iD4nHDDW2<=lXbX5g żڢ)5'VۅyjOHԲeKZlY~=Q w-x {S*oN}E4/#^͐0ẙ~pq``XJe?:X,$XBʑCܹiޮ+u=$x'e=ڬQMOc8ƔRM]oȻ^;Y=jU Idd l6RԪ]cGp;Ҿ}{֭KNvV@?a-Ra as%fάXj+qv4?g/Q/p;9VlWg@`ִn"#5 v2I^SizAxrEa;?z6S ֈf.6 } :8Lo_ _l,<=kֺZ_QxV!4$!9+O3=Gme19vQ~G/vh'2(y<n0+`)+6pv&5)۶'MXewp@w EG->( O7aIK|8y?Y!O3fҢ85/ߦKO_?ݍ~otÏLVj( ݌_˜AKm5,V yYp ݇gKMìa)4IWs^ Z-J_ʶ±Zqo0d<=O=(PUvzNwDA'l`^%=ʐK6 >ƫ|N,7q|y} +SId}kzk0q:2(1Oe\-L'}{pf6 1~Ѕ)eĉԬY}ʛcj  *O\EDDDDDDI_3RRs$f^#mYTw^Pqt7̬ 8^7CQl?fmyl\2/*^ʊkLL Z*q{RRGu*$DXWCuvh1 ՊiAVV6'O-y{> Vy;ԕ2޻W2DDDDDDDD xgҗ!rIyRSԬYvϭ]y-== YShBp 6ۍY4 K{ Rv•6SSB?aܹ':I=LeIH勎˨Gbg114/S>qӊWhBX,xzV%֯R摏V~Y7eMaDDDDDDDDDD~Ti6J_տTIjBHPBDDDDDDDDDDD*"""""""""""R)*uajłbQC*.W^)/Ny*"""""""Շ'CʡVYԳxzzp8*;p8*s?)o\EDDDDDDPb^U9q9뀕ڄ%33lnweJ~'n7999deeSظHɥQr(J+u:&IMMS7_9X>W>T?4WUŵr\:`7!.iDJ)']9תGtHPBDDDDDDDDDDD*"""""""""""R). ap\u-"""""""""""r9NlYRAAAdggWȅȕCpppuIMptVt:̙3UȘ IDATxw|TElI6QCzAAł(vQA^Tް+]AEwP顓 K}!̹笰s̑beyJK(^l-,I$핔qlT988kݸBB8aj.,˒5322iӰ钶JZd Iquވ-];;[YYYz'lplvN\.ܽ=(i8eԍ{dRSS-4OfI2MSWnbLLL#)(e؊XWpDDD11RSSeZEi.tɒ]CBB:*'T嘪lbH0ds:-^rQE,7BU/ӲdXVYIE9I@i:OYB` rlQvWԥ2MC(:pq*4%I^CE!d@ Pc2US)yԾDy)%P{N/6.ս ͜?S vx뛹ۘUO38[.} "LAwlP灊|泣N#g&EqyV:U ګeIJ5U۞͗ w22Nvԯǜ}Pw)O[?}U?nwuW䬥kGKkioV6Z/CT׫w5`Nuu`yj+>zmڽ[I5=Z6U W"2pO(I EIV/aTijx008_*C-i R-P0{i̬{u7ןGԥCR)[kΜ⎚rҘYrLܫus>4j?n۠m#,F|_&M~էOwW^3k^&OI\ gٜck558 ӛS)vWc>+?HP[_MrO=[I@T C$!ru.m^D{->7iyd UkQ͔Ś2oB:+ʉoxxz{}[~Y=:]"*5L>m#syon%>;8K2DIkLqF?ȒOVf*ȹU߾6Q[\h?1*uj.}xLSZ(^wiC,g{͔^C>UV.u)}O^/:3I3+/VFW}@.f}ջML}p(R?tk)ӣ }q=vI=RM?& Td+-+룵) Eio!'z^Ig!|ŗ lձcU9]7~;TM2}2=JUJ)~DYZ&.BP-yHEUm[v;—_feld*~랜ZG(*BR>*of4Vj{f߼ CMI^Cceru:g@zFıQlσHB[Pզ96"wejТbI$"$]㫿tØ*FO+-eʧU^Qٛ yv*HUkT}fpU)#{v'XU!_1U3;{ݨC',u.%N)NٖtED֑M6}r1Û'ʐ9+:O;}$!sMU:vT[~x\T3W {:4vic&kLn]5p/OI_Fݦr;fhqŽdh׿$%R |^yX)3З5iW\+8:h+Au4񭟴Ôt[?XxX}b8c&I@A<IE-uFkN|`E>~em rL\@h9&SLEX93 ~L9SA ̏)'á~YjQ:jNMg8SJx)I.@vw KeBm6iC^$!e[g3/HB $ /HBpd\`Xf?!E:_~AI$!_~AISd&=DHuS̬Bynh~k{ƧQ~}Gܛi^|Ff^CWdT& U%)Ï-?%u1Qg-Ш*YkQI_|M^!K5e4>~m{F{5O#}Z_-LR[Zs`uproqmtL}.=g~&e.:]7w4+c~OU\BvIR-mDՂԃo6R̂PQ޹]#KSq8 Y| ckpM|)9Yz ( mF^tyҖ/ҚXuNޣBTZRmtmպY%˗J?~X]q5kվw? Wv[k5Lu@5wVS5[|[`Up^5N[}BKʙPؾӐq$VKbrPvjlBڗ^u]X4azSf};)M Ti>V^fmC^Иj/5\x{)~iSU/Q}Sicǎ#?uP@7iZXv{yUcUDOpcRڊU^֏o6"F2|yO5UU m}5JN4ڔA <~pQBFRҭBۗVR%B .R%<کzwWr}{UFު{z?W)ݒdUդFպzMMIyNW/PQUTYU*$Gݣݨr>VӲrfKķVb߳: X@/rLVLSݺ7wk$&ᴇC1ceҭKS7 R`z3,YVZmjqh{m(v*DEz<ҕZ4+r2MSM&u>N.W Z|> ^##?8J[^isNC|[)jtؒfbM5r5Ԩ'hkWU_1Wr%a/4k4S=jݳl Ҧi}Kx~m0YB;mJ!ɣʗT.T{]~F^~ݧGrcQBAjĄG|NS.\Ŕi?wqǪx zi@z}jXEܚ=iڄ5QD"}O4T}2#i:8X5(0_5B#f)M7lνRPhAAu;ozz vߣ5pT=ضs5ekjW)p#X6Q}CAj@G1J[ڲ˩ڗP)(_J? W$![4 j1f#ZM:TYZѿ$"3W?SJ馺|ȋ(TAgW?wCԴz썞jZ&P|yxln2*䣯4rh~#R~ $Iܩ1QmWei Zϳ r^ЯCNQöuO osoi!!HOw:Yi5\^}gʹІsFw&t.B$!_YEIv:\`S?.0,$ /HB $ /HB $ 霼vj8i8$$Gv##35Xa9&$!_~AI$!_~AI$!_8vpީ_|uΪd+?͞Rm:v9Ug}gnF4TòA:z–߽v?˭il 7I]->Ӯ2y9_]BҤl":6)k(\m,xڃVz4 M1iė4z$dȰ9^RR2!fN}V6ϟɦd+F]B@#T@lb.a~TWnsϗOۨ  PTZYg'u6ߤIY(J-U/[z/yh?:1PڵSlrwWchظ5޲jVAiG6 }5s0wkwA?nw-釚p 7 ѣtV3?jj ӗܒlT6~(qwbe :y܁u+][}W^HӷR׮RuNy@~@c}U^Ww/SwTZ"ǣ;j{VQe-ڰRKaIC2*Z]o)dkӼwG$fOAd7QU! nbT-*E:nS6avY(-ס4%l[䉪+㞡jJ5hŚtfd^lo,.-Z:R匕(^[oRvvmش]{TjթT;ު *8P=T mc!o9e|KQrڶi<ՠ~WsN=HuA\l>Z?6]mE-jDHۥKѴ;]Wq̷=Q5԰^lJsUT}TBDUސ?KڢW'qQ:%sB 9WQvo<1դ~/jm=={z^kXz|Ws_īu$!p .@>5^/GO\]'gY˭mS_R~[~U Kڏ,\þ쨺Q4eH$~{CO,Y5SO'}s}KO_`iߢh֡o*=sNWsMh5q^JpE Ctg}dej뤗ts?h5VS־Ƴc5*Ѣ*&,;Ͼ a}5Y+Ez]=֤K׫#oTHD;YJ8N1[njײ) ュĶܱm/RTW+i^$EQFed_OMUZ {KVxVvxB䒥 c$K.In[Rj7rI>}uL읥o.UTgS[g .sncKtp ޗEVx\kN$!*Y:*AW6H'LVB*ljخ")oea2E(Yz} X/Q/ohmѤWG黵nY|;j܈;X{+%T]u-z*po􏷦?D?k)Y ΰ4+ɡn[QԨZޥ\آ\ePm$G=sR=%ZR-ߜ Г%PxZZzx(ޟݶP&IѽQߒ{Zq@V1!J m~GUPp\=6ꟃJ$K׌xYRXJM4INI֜jn$☧]RpvxUUsi留yӂ﫣YJ^H.ݩwr((^8غjݺ4'SoN&.yPONU=J߿nXM*VKwvdL p!a&򰔸|fpw~6RM>+a|-NrU=1MS O )Wno4#)Hި뻖!SUU̔MRҊ='򙚾-WQː,SaJ-?{]_v/'{k[VBWP?,-`+E}X7+!ŧhݖ=ʰ**HdkZ")ګmIr'ju{E MFU>q#1sUG_MV+^2dU;&2S\QQ ȩ=-y%PCeZ}xGyE5iT8*jtS9/( xxd>_FLԶd)P ,;j+K$lr廜VqŮB*G4M%N=%w[IS;۩K 8]p09%yԂyk7^]RRZmUJ޳S U&GGr8ϒ$}i9[Nt_PdʊtII)kL5;g vUp$C6qr@rTXx^`Ō$E˫!@]*+:]snf,j"[J*Kj.Ce+5W;ō=P qMv$}6VuT5S)6zgtMpykUY  (SEڵyf.nvl?Fq*u:!03oVm2޿Y'I.Ewn sHܢu*&aRܒ$T/ӿ)r4OGP' {LF "f)},Mڐ&)T ]hCVZMBi 4m>u^JQġ_lcaOePPh\;Ҳ,)PX.W;l^9Nj{iwĦq,z{ ?>87Jc/[Ͻ(qU ͝][T[G)rvr}v^s-q)'-E^I(1 E࢕PO}5B7fgUIK=n#ePX'߂zzP|VZ[WU앚KL|I==~3?Ӹ[{h\nao{[>B{놦jܼ9{ztm;_,eRd>BS [^*PTl ŸkӿoK< #*D-4▻'np뀖M]R~#n*eH٫ =zjKoNǧ6팭&aR|*mcyUF!i:Ub#'3r؇9q8G~< {+ WεϔϽvK|%A.[*-EׯX$b(s?PC^jFp]]7-}~MҊk [SGh>Ԅ)˕cWZJtٓ(c-ۘqMնV8 zE}_Mjк}ɣZjmgn?:z(y>\S6A2WWQng5~4mtVjGo{@NKe>*K%/c_SɭձJaPTp+*bO7OQՍO3h_2Vg^k.4hzZmU3!U.V|;^S|)Բ+Pl^ZbR%HOwƵ+*(<sӵʬꥃS=q^)u['S{Iuަ K?=5j)o?i8d&N& m#ia&Nu@k'!_=aWIumZD1|TAL-:H ꅜ䃳q޳mթ IC%R{Am6_ ffUOf!q[*p5諆RqŅQk9&$ /HB $ ? c?~)~+/N{&DfjR>[  qqI&-mq-۲tb)_~AI$!_~8زIIxDu-3@Q1%Urճݔ"aܨj#A\ώwߓ]oz}vjU^nJ7*~'AW gǙ;¯I[6)22F!aHOgU!Soۤ q#8q=;~}&DrR\AQ݌1n?E{W gǙ;¯I'[ӟU SlnF7=}pr׳LS[߫yq>$øGqz~rLO _}W #/}|e*==]>vnF.3v-!CN,wOeɴ,Y@zPҡLqOX~T.gijj]'+(˗qRڃտP})93!S y+W,W*U"H}z jװJD/!%CZ^eR /,.O>Wˇkx?vi߭o,𘶝k?5=j$!1,9Qzz$@rFǛ!I| ,{R'vj1z5ޢvV$LS>2._Q/}LYYf, 2eޭ+iPyoS )El[QzdcgdEE$_4Z}Zup^n*ni?wp:qXr:`B-RMmN)(5-SaAw~y}9oObrbէ]mY)Ӵr~,KiߖjP糐8cv.{ʴ|zl|ɢyr/ Q1?,s5x@9x[ywpa*C0 ٌaHLI>:|^ind +ԮRQe] Nu%;ˣ,̔k*u20M-odĶQ]u|uxuz].ݐaӹ)et}ݟrlT%luvE+ҠJj8k֟/j+`w銸,ܣOަ+OWRY/.atRWk[%NZIC.n)_5>^*Tm۷rŊwEoEEEI!CN![,$Cs^~;#oKdf&jj䣻5݇&|=]6twRR3JK9xt)IYYf4NM'v&ǜ΍7gܣoRhۖ= w8/݊qoCmGElѷ}X2{;rL+g_%QϐzMgxdFaktuT)ȐupF̞|ˮ.TS蟝j}uʽZ_jٗinZʻ5/^u|gWPhpת N^_ h$yV}^EԉU85̃4u—ijuUWֽ8^~Q2MԿYiԯ^utpˈUti`W[G/Ҩ)zJ?K+כú?z䱳(OgU|z.zQYN 7x\.y|g$r߯*y̎&CVn2"MC g$ɦШ*.(rj.D:N0vtc44ҤGm^;!ɷ{]cj5SUzFL˒er::|ֹ,˔SvzO7JyRcv唾£uY1-eZx?_(,ojlU@ >Y1O+]ꫜL|yUoq++l#N!SES=}Ck( jjh^@ g;m7E{.{LT;~[;VE$6L~.UoJWrZc3%ΝdЬaC;xsYٲʴ-מZ^K{\3^ۭzfp TИ'zKzkNbN<{}E-*s~^wݪq;ܦiUt 7ћeֆ fp ΅kl//<_w`5+*{f}ܳ!/#iU[=u45:hM\Qܵugm^X#;Q%{8w5W5>|b8ÊNGSXVFS{FTv1V®Гc_Ӱ9}:is)'I>m[:W{:%[ SfGYۛ5n!^_LPPW2L+^{_IV=z_ϏU>?WUРAúaBJT\ U;aKHW'[n<>I^Y3wޫ/UV}TL۫nSnըBJ8q5{JztJMiZd)sz$y5} OkU9gs}*+st}U7 j:U*N^!ɒXW\VjUUmիKem]IܳjݥTZmKUVqUT^lijɺʒ{4}^V_Īn!e;\V˺I**'X3/WJtm\7]Ͽ5f&lj7W*Tn u͞Nӫi+[}P^yiمw~^Z]}2MOkup^!8嘲=^efyeBr׬X,״4-Y?OYf,٨c:M1#;Ys%,SiI{<'[qZ]dPk삛TRW٢ʒĬMڱy{Deeg)\K A7 ISIzН/+kb'Y΍ :Sm0LϻUeFh_ t$mq/mڽpnJMޭG7;v,҆~5TM{74>9Vz Z\5d(82F=;mr!ɔ>}=Qn.S NBV;:(JRj桞6%d_ʷ # hv؟,K 6۶QJB\J*<{'_~ ̡Dı l )-gfmyEeٲbT%+d)e)m][@i6GF(LeͺWE\'H!Q%K~zF#CX(##٨rמLKC IJ޻OAJ+ Q.5%噯Ӑ3=:gkҭrrRv>8A!.,+5PPNKқO; c)iz }iICtlɒШǜg3fwnZ͙\{iU_o: IڲnV;81D/~N4iY`Y7Kno$J5꧛]ۦESTd!9q\%tj%Y$IܡugUԭo;'h&,_C5pT3dKUsJuF4=ʌqC_Ҹȷ5Gs9 g Qi:;b>4NU5C*tex ҵV^V^u:jȑ)$/>¯jRVvfY1Э9aDO6{h}9O/ +zG"{VSHn0i9L?Se{>#e,=-0chƍڹϔ+bkoNXstOLPJ w8}cM nQ1MF`aؤgã(>fKnB Ex box\ml\k\}jc~wܱ#| *,# xчE}jy0?Q,TMs&i7jʡ۾BO xÔ'ڹ$GOJHHԉ:ɓP7,KڛS6S^a<4]yyS;7׍Jh\T;ީ}˿U9T.Ӽ;*vroH}TaI7Joo֍dYqr:]  t(p_~YJgiׯiҾ%߳NoC=J]IWTZvlPWGv i#&jTtttuvr>am(NsFݙ(B2<]uɌ`@h$áF.Ϳ7(Ьh+?N[b=rڦ>,>C ռ[^PV:e:GKfܤ'_ҝu^jޥ\I *'3S 1Aou^|jnv:k٣tġ]uS}fC [RUWIyc5{CpF`6OVrIgωʾ>M>Cg`7r2M߆pz%_ۣ6IB )k u8k.z=H;.>%=<_T=+ywG}>{&=t=w6QGB hcȲ,վxaAi,mYTɬ⇩h ;IMZvt*j| MC2:?I#(E IDATGԝS ѷZ>gVY-3P0֭HMq&r:]ڱcg%Xr5PoǾOM5=1Gm8NgގM묛(TEz=H7:kۊEzMJh7#R4i}j//we'׭Y^WЪWa]XԨ?_LcmԒdZ.x*DRM}w8(dr(tK~~?y?YON6D R/ע[Irg),zʈ'%I@r}]Nd W/oJ̒[,?[E'4yk^jtGzjwq+?'B *TAn n2K?PAvٶy{UzPs T/bZ_L%;'u=4/dԄV^3T؎V@,UvmEN\x5hm۫_[` Kl8>SmvϪV9fA*]s߄7_]5աx۩:,D_/ Z|HFF $58S+IWmV}9js)t)|Ͼ;wjUo}{.NG;(pI5iQ5jpN$>.^(K9c5ncOnQv5684PElW{]c#'[.[PU`P.;ݨS}>=خQ917VA~<$;Wr |j$ݨS}>=خQ9+!Zm//Wy R- ʗ_ZiTF{AͰ]vHc~*fݫm۫K^F8o׫g lȨapܕ\fzw DҪWsʋo@IV׎cE` !-(B[PlA؂"E` !-(B[PlA؂"E` !-(B[Pp }]׫^uTJD[EI"'589bHB"R^3skDoB[PlA؂"E` !-\@)ܬeOE~ TFȥf%*,f_vmra٩˭Y^9}trVe5LԢ]'ujX. ֊B$G1E'4rI2UW(wbxc͛K=x.Ru=I=IRP;VэS_ַyʄ{`Z-z-d9^'nGRqM=ELT Ɗ5nUM%M/lAد }z|K񇟪ˇW[3w,}^ַq jw }GFNL{ټZrOz,ao]pn/%g%R! 5wգG|Mmܭ5.֚k܁؝:{?47z[_Q"$Lz>5h|?8N} 4e: ڭ+vKS^ dȒ+.^C23M4W/]p5q z)s#YOF,|Kt':dLO^7d)g.%9<)J _pTQ,r,TMy7whƶG1WXMT/ۼZ ydȐ%I2jʱ*jɡm>;6OWkk|N5n.4U,IVNth=`̺P=ܒVmS1Gh .-;]qb>޿\iՃ֗e(ϙz-B-$g[]3AO\g6o:|P3}}H<\]xįBsEZ0QOW+Pu?r8to钔4=g[TrJ95#F~H.۟@xu\l4@WO:K_[_6-h~}uژvG /iu1j5_^O[J }y+rŔZN[5jpFU7ܽW=ޤ>M(B[PlA؂"E` !-(B[PlA؂"E` !-(B[PlA؂"+&[~ݠ}{W tWzSZzclӮV@t G@B@onGtWڶU?Nv>F@t!W8PC(B&ȗKj@,iZer^>0jr7 !iߕIt7T*sj#D q ~!wы Pr# p Gщb_M@B@vL,+=g@l#-nP!:8b1 @l!wvL\ Qp8b1 @l!wQV@#F [&WB+@#F [z!1vbq 6bBEK&^{KqG'gfz3~aLy/hb?Hw Pg(B1vAhm dROK4}"%^:C7PFN!p)e'>4]puHqֲ"Vzp7ВԲ/7(7PG ;Y[=Z0F}xzldWyʌL`F6t㳓54-sizdh "8 =iktܴܧ34gyc'İMlU,[fĆr~58+〾4oWf]lS$rr:u89k5S]J 7nP3<K;o֒n LKz.\nC)߆5uܯ'67Ѹ^Yܯw+]ӶK;%eI iߪ8+q&RZe5swm:G\r9BuK[uJ'\ +r9zSc(cc;\rp cK-Sc'İ=U,(==YfZ5 RoUF>$z%Ӕ%\)yzuFF`vpTtz߬aN-6rs•yZ8$/.К~4B]8v>QPѳ0AY$9&RhLߧ/>|2URmwo9O!)2!YjNGVG;?61l㳊e3N7jq9dZ-۩]ޮTPg)E5u3驇:}iᇕ_Üh}5/,/_: zb룔@P$˴\^ "fZPqJ `Jb  БgjeSoז[?hj`Wzw`+A ȷa:lgZ=<<:ezgS[ӫ }hHus[-ڴySYP5dw@̲9>[xzA~ Me5k#䑆D?x69Du? [Aհq}--|MJ2+!Ym`I瞒zt@cYR[2̝[zEk{Z9'Em/:-/?ɑdʗGfJ0r-Y2±[Yfz͏ҥ,Ս~ce iߑn>R1bU^CiݫEWN@EqI{6WO Zbw>bِ%@Ko9KK%p*pe,m6oWѦqu][!)7j엻i%OUjVx–BFk9]3[ 8rwÐB!ǖeIs}Db*$)NC&>ى]c5SYj6oW&SmH-f:1lz, -> ]xVPCtj~jj޲*z܎ Kh3oSg=-e'{Ѫϗҭ#j~g+;sGvaɥC脤z YP|_UƥC饋Fx#tLP_/ ̆xw6j2۹UjDi%aOmeJImC;.r8P]68hYA׍9]g? RxV !@p%D .CK+BW9C9h=iʨ.wgTuO:[s%ڴu3MƖ)tKCRZQn3XjV|Cߢ#Q5TB^bq$)Gýjrȥ͟酅~{ߔZ~?A b>|u ȑqnC]"u/kh;r*uQ7WãM-9kSˮBM> ^/(Bn~{j]3vn}jf]b:J?AO<.ZKjZȣOӴ * _Ȓ&P~~ԯ-[z+ԝxӂnW'ϼOvW WD>. px]zhё}^_Cy6/$"HҠk&jv0tgaSӏh|y+?n*7V+qSZj9;|58$G~ Ny=rrg)bӖ L›YZzd/ I%$tȐ%3Wa~%׆e.\ggt+15Yq#˗T҆V^CG>H ǹ0,Y*ߡ:ppE Wnq$QOJ(3y6|5c f9e֞1O7M䳫#^\\ey&9jYإrf+ܮ7M//^\l3r7ܪQ5} m+Թ{J{I%}Z];ԪKqW~2X|e]~z1Gs4oљe*p1lhWP |_YF0O9ݣFDǑcgv%@WM#F@>bݲ *d0okPW$ks4n7]6*λf2 XZZM 5,PAV>vH]^hE!HQ䤄YB>8&b0s">U qNHZ$C.#K/yF\T n$O(B#E VD1}O@U62r6$ɒ2+21V8\?^mdkEd@ @l#-nX+-3xм@Q#8b1 @l!wQ,kP8b1 @l!wpDDBV(t7T  vW;q D'b}5c ^nц1IJKo|yI r |jޤc :@i_@"w6\ !UrPor  ʗ_ZiW1]a 6/n D+ع_Jkk۶Uc @m_@!wF!Jңo@#F [:܎ ؂"E` !-(B[PpEd˯o  PqJKomj90hqDr7c ;(B[ۑ}#amӡ1]a 6k }1G EU|SSMN//7ԠLYmh_1}a &k}1G !iߕIt7T*sj#D q\[=@#f;(BH rܑ nj#D q\[=@#f;S1ˊtY1ۈa!F 8P(B >m0P@l#G ܎ ؂+!JPbq 6b{ @#؏"Dbq֭_'%_Oqnt.!F@Cy IDATgciVxeYԹsܹK.;=>+!JPbq)e07RnnHXmp0_Ń}TY!3d* ꧟~R 6+++[OoZQO+\f \QQS'<*%ү`~hi1'hI7mfA}y| x3_ѣ"z`ͣGME\<2\ vZ#&i5ypMHM'襑4{H2\JmI:M5DRlpyEèx}}W =:u}?!`82,˒a Y{>PBW)I쿟!ԲerKzw鷿h:vS>[Ƕ-ʹ4f`jG)YQ? \S.WB`G4 |q'U̍D [Ćr~58+u\^KV~[JoA=3N*Vz v^%/4{;9t 4q`;dck5Sժ-! ]=VK9Bq7ВԲ/7(7PG ;Y[yt@{MizdxXlp5c̓J!sf-fp;Q4eK_|tؠaqIVu8(FS7\r9 ܆$S K5kb%_SOl* #NCoq}*/_c3OWF,v*n7jGdVu>޲Inqʕ`\n2r%vϼM/XJ&뉗LS\r9/7j*>r;e]*:`jߪ8+q&RZe5swm:Sy)7OHR W+iκg +K_@kӃ InG^wk؉쇺Sogn;,]ةOޥ] jƽ9qlr1P"D1nX-55%]fX,K%I94eK6vU|[Tr6ekY0RNa4*:a!;у}Qg}0Z{նܹ7*!ף42훐vYڜ[2-uh7@|d'}vg';[~ۆ=2s6גk3P j[q$9[u.>2搌jz0:P_qSa_[*s~[Hgٯ O)2!v]a)XPPTVH2JiT}JbhkK)wa,ZYfJO?^ KLQiR[ S-v;h-gi$Nw?SL}`xYS=ʍk8x9]49m Isu`>s29|0`Յ IQc{fM/9xx4SB8^Ke&cMYenQ!Μp޻!s=6]P:ʿ&D~=.N<:;WV[و4.ňaIRMߦ)wI>(5ݯskӣ#u*T׊nPn߳HӇfe O9yJ9V>6Vp믾ᆪ-[uV˕wߣzP];kQvkh/T|~!\mu=v$M:K_ԴhWEeٵU ;+)T%I Z#jR/Gщ}asoL|T{mճj`s!>5MkڑiSCCg鱅˴|UyDw6m>ňL0F~X% yR*>oZRۥX9{h#Ҍ Q{MqIrS;,ԗ'SS3T$e9Voz{$}8|:z!% DFBky:;iM~}m񗙨yG>_{Hf$H Yleg+yV2sa(je&YCtȑ4pۧkjRŗa+R{O76` 򲕗'5]zfkm~U91"cN-`F.mN-F恳mסJ;dR9.$ujjoIˣ 8=]eqvvg/fe6>^7owXkT-kK_^8!/6*#'WãM-9o=n͕lfjӪ54{`]KT^Sx(N%m~26륙S 4 hOm^NIENb/bOkrԭOMӬKRd~}4}Tw .e1_BM,J~N96hOV U#$|>%z_oH)~|ءޑS5KFjriQ#eE49wcC V]rhœz'ǞkѼ:wz6 O7rt8Gӧlҕ3sgnɵ< lɽYAC>^-:Rs.]Wh?]:wՑ֓u+/ 4蚉f]TJ zwp2]V[BG}hPaU W^SxO@;U>z@RvtCŨj~?֬R~kygkފ}1EӪWa]#ݍz­$9WXT5 ${*/R|B?<eYL›YZա,8z4Y~2s_0i|֥ ?8;UC;oרMFztY#y[m/‚| 8P ZJ!h\wR=+Aqqr2 2C UPDo\S_nySee*? %&&4$+`O< I&:˖_.]^%'9T#~pٝ{-kɓ$g G>)]JHCL3PP~J/oGV>#/םqm63w)yoq1(ƌq㈗7+W0Wٹ 9 JH!KfЯ|*7CMks)A\-(cnқ&hlDN^ڈyIUR?]92ى8b ̭58YݗV}BtǛ4PҧյC^_{&5UNjTUA]0R׼W<~~Q v9X!>emBۇ\ Fg*f &c'9%E V^^~ݸyÐ\.cN\.n9N9N4HaI"f?6rf,ұ%ɐRK;?vJ0F]X(AQ';JǶ1dHxna jc%{a7F\n܆$YBfW5 ˽3͐~-mp؈\ Qbq 6b{X,3xм {}ı}@1ac @Cbq .P(C(Bm0cuEI.[P0PP0(]|1a 4k}1GcXx"0I@t"W8-Nn @lkI\ !UrP 0 B|y9*evOхb_m㸶{ Gw$q%DXUZ͆Hw@X۶եGOхb_m㸶{ GwP(K^Nm0P@l#GclA؂"E` !-\@4{nwevZ81 ľ?r7=E}tu;o l׶yw:58 1 ľ1 Dr7hDBEHMM79EHw@XR2eM*}@!W8PDMIObW{vW;q D'b}5c ^nц"@/nVv>N0jr7 c*fY?8b1 @l!w }1ۈab cJ|}1ۈab T"Dbq 6bB5-_bq 6bBգQc r}-Z2*_;R7?9S5՛Yt {eʣ|AydD[:C"S ׂmӚ< YiO^Kg =$.G )^4p=hzE_ɸVso;U% jWZr+ݎa(XmMǜt j꺁 BuUWHVhkojٗvz㆝<2Bkr;n$Y:чt~pݗj^; U#mVq]Zwy%:Y׼s|hbHӺ:γkmz-xt]/މz3jm'x?y&lxsU˯6ҼSz$GjƘ'tC3zZr28vQXw\r9 ܆$S K5kb%_SOl* #NCoq}*/_c3OWM?r)iIK.<=FW:##<@r;e]*n'Y?G;~\G*-VrP#:uŗ}k~tnK%k݊uuޝNw\[{c6]zJ8SR& Q!QW.?#+IJUYumX^ײkwUTDD&&!dʽG IHU&3|޼.I3799w9g${tz)$},UGUnc;uPJq?_˾^G2HI+bc:=α$kEɸf&d(61V @C [Cq JJ%.}ʉ*D ~x^SHaj+hšrQM IRĿc]fOc ʶ%ɡ4l,GֺʽZz[zxetݘߩdVɱuyه5:=3x;R8Ft=S54wúwA4OC*>Uߞ-eM[%؇:Sq`:R6ns~WKjd^;?%S]\?{Ǝ-%C;u_PM՟rF.T﴾LOo-M%7O+\NPM FX]y㫊\cS~۔i s+߅;7i %FmU(lԁg =;k~)) (+rܥ/VnY^@#zWQh(7(N>O@9=Qݳ֊u!Z.Y-qǏՈ_h醠֭X$s`uqШ^׵^Vtz 5Njee˖e *.UҎ$ ME6PǾj'Ti}}{j5&5hZ Q& ߀lI~}rvGGlߤ6'Қ_תgZ~WǞ_Գ܋UmJ\/}}t/]SO~.;4ve&aSiתOyi8êt$[V|:v*kvא4=g^Sdݢ۠  -:_'g]hh\P }[|)NKTaG/`( H(xnG 6!T?j ڗ0!S] 5kFM~wCz4Y) QplIӉ7ީܢHѽןxz̺R KCǜG/V%>A IDAT-+Ke _l˴Z뤫)w*1,a+g̮o&;9xB^O~)1b vhO-%W޷G;jHSQX-Z1ʶ~cqZ0MS~qCAu]k qZZ0q}ۦ~NWɠkG 68tuuNœzppzoCO[TPCu׹/] kہld$% Q dUqM{ϩQ2a?W9Xؖwmզ͹6բus퟈W1Stw*E?(֋*{uLKK6[Fp~tU.Vݝ7Qm$+GKմn[˺;k蠮x}_{;ƌخ߬^|oиzueJkۧz54$@ї77.TEuK;_Jǩ&J4$!^_:M?xP?pEy*%%߸HxE $Kթ:T|j[2F'Θc{)P˄#TaCչyIm5x i, _ۺ>%AG HCc{wHy^IiwH^WTk|-P©z9ZwdiE ܠ֥܋xkէ/]j 5kuQXW,ӠCGsӜdFzJ-Pf.FV|J\{a8IWAJK?IWMU  z]Z&)_WaN%6 sT/#V r-SǶd$ XOjmk[j!;Nqq1r:2d z4ۈMR!\r&+c(/WԵB׿#*-3)I1V}ߝ鈕'#?_%i#U>B.@B1kޛqVغU5j.R\$|y/qkퟟ9EPް;6k$M>~o>[hzTzOBHI_vrem8~ysTx6*\y})G34gnUp1՞[d v5z|QVPڷ)w/W<^v :Z<Zhrݴx б%ygAnmڮG?}bu'ԥPQn2t+{dɣS\\>@A/J8cW:ےiY.0~z߉FT?(ۖdrDv9ó4%$!JC @Ǒzߋ:CȐې$[iU9"1Z8\d$D" @t]ݡcnD# m+h HB яz D70х $Dhna ԁ#II.[ w1T rkݎz D&0Z4-n rDc"Wp@%EEjֲ@dѯ@B"@a$2UX|AD3Ta>zծcZ: DcM :ӥcUXڱ%=4Wj>T/)>^ǍTd+GB$)>vF|Yy"}T}Vo.)͎׽/5+/?kS!kf }h}nRyOWv>YXYoA4j)MBIiܒ^Kr4S~é.7`N:M' mXI-kFOX)KrdIrxqI;F>.B<_UJ|~]=LІLi$]/E~=o9S'Ȑdm{[3F&TJNZz'.{K;>Sq5ڷ3}`y RQH%-V˲ 4Mҁ MBVkU4[P]E{UNzCCN]??=_Oߵ]K_7}&o=}ԻɊ$$!W|3_.͜PuձzߟiFv~3ϒ]:daJ[Qڌy'w>?Q֩&) K]ߨ? aWXA |9 iɌϰ;6k$M>"^-[@= v'!qj; B$  $HB B$  $HB B$  $HB B$  $HB B$  $HB B$ W PM벵w.pFQjZuF$H?^4<x{g1 ~\pFv+c:&l;%IHA #!@b,ю$H|$я@H0D(BHBDGD$r@17.[MZj+w: z,u=st=Ք R#NFk3HBE8K.uԖvp-%#FYҴ *?s>=~IpIAǮJLMSrl ܫ翥7WFgFCM Im4̠,G1a䐄f(qr($Y]ZZ5 ]A 2:%y CL*Q۶%Q1̺R KCǜG/VOf |HBGrh6ln/CdiRJuH$)N'=WeH)3KhHBĔ-@J?>-\^~կ3oV?rsD$cmnu7\W*]B$L "@ A}NJðeA|^%-9zhUԑ,<m7gOC@# ")IBHBEhGD$RD? 2٤!vp4N$!@q2`@gr.hĘ DԴty$$(4jEEj2#!@i)S*ϗdD ` jױs1FBԭg?|V|(uꔩ^# "Vxq(tL $HB B$  $HB BDM벵w.pFQjZu\{cs4 Q+(4J;l֯P}="6YI#%%M I*,wqh5%[mV%6zf"K}bs43!$ݳKqpFIPnGla,uф$@/bnZ#60DhtLl;%,f;(AW Bl tL $ QtYDb3?%Blcr:]**V]$ ~c8M6ɶ={ira.hH2Blm[2 e+-iؐJMMu~HB/@d!6 a8d`P:mT^^ڷkZ4+͸ٺ}l sBlI02sז)QdnjV'T=2wUw;J~O :Gf'`"6 öm!Ӷ{o񧊋OPJr^Hmiva(&!]z ёǝdgm\JiCC8AOz)Ӑ- \{b*O髕kR 񧟮1teKuғi\Ҵw24뉳UGg1:?iTFB{^;T$DS@rr X]r9bu,MQӖ[=ElI}}2b%M\" u5˲p8c}|:%&&jΝJ ӧjIzuΕǛtJMܯ+Oq2qv @Pvns6U^*mӆu۔'%Q>2nNb>Iu_ǧkdjMj$!JnS $9-ud2-ծҟ͕tJԲEqLY{ QG)0Zwh֭z'4m_dU 1sN{nJ){dž(о->{@䢾]<CK]>P6oQuх*)1YwnӿخN4%jYJj+g̮%`֕ZU^:\=z}2{ӂg5qW48ɶg +1SВdr@â)xhM*_yG}|<ʐ!S uζmp{[Q];h^60(lTдj)|5@ HB ?Oy9xД!?w?xGW$n}#>ךUԷot6,VʖQ A{)9-N l^~qW"~U@d2>>x~&Au.kL{޹JdPbj l6v |ihW}C)͔zHG]u%ҋs{zpБ(2 lٲ}֭?_e\6:$x]ڴ9w.FZn!. D+p;ᆪ+~ppcjڻw;0uQrԦGNVםAmݽMIiIX1>ہB^LoWǴdJ"?W9V4,EnmoЂ+tfɐHMH-\^~կ3o.:NvP`'뚳?%л'4D ɼj"_ϺZf%I1Z$ӛ"GdU܊OIÛ_51#Vf0G~޽[Oj?Ï?R.]+ IDATr uP~>zZn|E^>rLmF}ztJ۶d% ZbRǣXSe*h;6|ʔd8c牗)Yl[/OEp)&6FnS!ٖ)UQQx%)wG1.9 [T_[=vF<ɉҊGt_צ*m3uYjZ;18Xc5yT&QiVK-[@= v'!qj;#!$>~ysv[ښﻧڵ$H9Ex„ ,+W~ر|"I CJkJk\m4r]3F99$xt`}9vߦm/ȕfj9El+UQЫjR< 0'i3dUTwǨK*" Q Dlg^g[2-@(E @d!6!CO23u@)+I4D )" BlG])" BlIRU}b3 ~G '\.L3b\nwhf"K]cs4a:&Ii*zIH wQhԊ x{g1 ~\pFv+c:&l;%IHA #!@b,ю$H|$я@H0D(BHBDtL ",,,]5zqy19Xel]kkTngzjꔋӭG +%6NЩsVl[>]cet ?_rq3@~|{;}XXJ$!@ K2,,}qQ5Ojk֫Oܩ+ǵ'jeK2wSꗵ멺އkkf^q^YS ۙCvRU,9W?,^*_p>]^i},UGUnrHyKw_l.S%#׈,tL 2Z$9-ejӡLմQοY*oɲluRC-M}Cv)80K|UOSN9?ꫥ5eC/~֟..ɟ\ cG떎&hók^uzfҲ((0hlS (+rܥ/VnRQh(7(N>O@PO>cOT쯵b%@uHKlD{gic5bZ!()u+5X]C zv<%46-@e_7یQRC }*ۭ|OkViˊOU[Nz-َokyjV֡[w4_kL˝6SŗsT2ш$L]Vrv욦-ء=lT}4k`!YNu2Fo.chIƜ*ے9T_^kiю4[LlVktT}=a4NeUU.Q l^~qCQla:&q>X] [v'Z/Kl: Q1ˎ5 8Ӑ9wUJ?Z\QzQ_VhH5[,ڪMse {2J^Ғ~tU.Vݝ7Qm$+GKմn[$YGu 4nb;ƌخ߬^.7RW[W1Stw* c@|éԶ=dN1[S(([A%6]O>^JVǜf Zp#5 }﨑/ὒTKf Q_zN]7}A?o~KK?d˪US|ˍ'RClYA|^|5nصlC}**KNJy.0T+YQBqLy_|i (GD(^zB/onykΖ(Ta-}yUSE*)\IHAHBDGD(D; " & @sq" "i] =3w1@#tL ⤦'!1EQ+**T.h "NN*,WA~ #"8`PTTU]Ј1Dn=˴pFSL?(Izċ#D1c!AI$!@H!AI$!@H!AI$!@H!AI$!@H!AI$!@H! wji]٥@MԴtعNoV}IWTjjMΎ-ԥgG]IM법d䇻8@ج,mCgdV v |g{R'>4'A9wV~;^#ADr:]m;E,˥?Pz@xg9D !IT@;faaa=@Vڤ7G]Z/^Zԙ:ȣ5?韋 =\ Xj򱰰Too~AN,,,,\"#!4^=}29LFU7 Zѩ3_UC+~iÇ*[FUCNg];bc )ZO;]g\ٷW{wƦּp].rhd+?'a=^_*u1EzzjYqSȫ+R5aJ)93>i%\>~ &oB7xqo"HnK('YlrHyKw{Γ;t%)]lYڻi]{7  vvi_#"`𐖞F9y(ÇS/ qM}-*l;_6Sזt2s@j_WĚfh{ 16$;w6'Qvqn+wNDkڊz1ty )ڥJTuMj*M3vޗ3K U6/Б!c0ܾe7&gWٮvץmmۍ)7Q0z"=?ACtkY|=+2 XکUS;Yq\m4`G' um; ׈(N4S~t %zW}ͣ5N""-Bh,"~pćwFUvcLKh;&Qn>DabZ2;Hy)r:K:^>C`R㔿,g: G]6Mͭ(i=F=oܜwypјÎNcZ]>  tdk)b x| D Og h)=znjOPĭ|UmIDϤ}Y +913 e:rGەE.ƊR\T%K0{AMlR2_}ڴۥvEDv@rF* tvq>%1DA(DQ,zK-Dq,o` }&P8a.jɼD>/7NJѧ7@051^Fݩ-lg@rF VWvJZo-kIH"Ƿm|a¡'V@.mʧd%LM-P >7S95:~ ?(#;?9?(4 DD}WeWnݷc>“@rZ*hEUnwr{Ͷ..t{rq]jOۡK)G !"0śtqSBѦ! 7O3ճ:)m}S/`f(;$x fd`9Qvmֵ$"kW9_]D{r{(ȟig=BFl¡SRj{("";aC[(yuu4qj}?.Qzuk;p8DfV*+ȾC}oPn鳈HYfqYhּ%˖,5@ /9M88DU..""""R;jAܞ%wbPDDDDD-ZҮcJ]DDDDv4׶-Be؈"""""urTS"""""""""""G!"""""""""""{"""""""""""G!"""""""""""{PiHmEDDDDʦijr޵6mbْúPDDDDD~%*})ԎfEE05HR/Xb9rZ\F]DDDD$ǃ,BlڸVSCYS^'4"""""kg=e"1:5^h$Z|vڵQJg2"""""O]DDDDDE]M%""""EDDDD:q[U"""""vZ!t.#"gkyڋ3>v#'4d棯b;t3ϤoU%wXq'62D䧹\7ڎ2`ZV`Z$dt:#o.)'YesaOa_@/oy+XeRI&R4$CD6i/,"J1cA"[b1{@ZTM 7p92WuNS߮ IDATE̺hUC"`-^7cy}x0[>]- ^CG!n: IQ~\kO;zKpq/;w"*+8]uJ\hڔVz0)Y4A#.r_}W' o}^K^$m7c۸"e;c)~@:G."R=C0=TlN;Xņced+&/OgGVC12JE2Iz!3]dU_MYIt@V<6o̖>M?""ߋ"j""{)Yo7-fKsxe?aR<-uxLہxZ,vXNדD7.A¡P@_ŊiVr&3NDDdoSn]eâ$q mSDcE.bgmzo-YMvI,v.A2}+Og38KgL[भkZW!tS E?-_?bk{x9ykY=97 ENLḢZ3o<\<#w|K%jފ~#zTg+7F~a]W0DogE`&"R(P¼d޶ tvO|c=KVBXQQuC߫59^ňO/c6Ro#a?Cdd_ާpZ+%*(qh Mz0hL/)bfN",q% 4<]>Fg'}N"(u[\fĺNmoD )(GDDvruM;c@Әtzq]V|lvݺVBpp܊U1,Oew?c#ҙ:LoX;1ӭ, +օq$qj8;0nM/k8}6il !"RWmBoV_rOk죞b%sͳ3^{ )/_kو)~"/q`[7ySg}jߕʫ'1a`ՖFAm^Pt-C5\޴LFT=""ǔU:ZCyS/G nK3|=\'ZS~t繴K, mtډSN2ipqRG᪏saξp20eQ2{_θO/'x:q[aHDdWr>L΅|pBx](}5ݜz:9lkiw zpG8=/?24kӉ5! @w<[ x:3^F=ED ޛ>вmz]pՍϷg׶huƕӅ;I`W3ti?N~G&мCwNr''I Z_] re8}DwB5v/E +O\+Kp &U.' 8M.+""5`I/,OIPa0 B[( ;I$&&X`\;$%TY;q{B""{R{YNfwwN4Dq4TE6n}8v}m@QHQn]곮SBa|3a~Q6a 7cLwo!\\ݸwM>q(^o\ODDDDNpl_|vڵb=Je&RU\DDDD6!2T9_]DDDDv,ǃdY,[^_\SDDDDd6prWrHifq{&-[^CsZhIUn+vQ^Юc}b#e"""""R|'T=BE#T=BE#|=M7Fj{("""""uߟ@FV6MTEDDDD])n˖|MFFֽ"""""Rj~\ rWrHifmqYy9YS(.*ለ9)bXb9rZ\F]DDDD$ǃ|'Ħ$'0DDDDD rrHYfqy'D4aY^h$Z|vڵNj*."""""Ո"NeDDDDDrT'nJD$?{-u0S﹔,P㌜c%Am*gNŢX&sgU/6')hLgH/ i#;j_| Н<>/9ɜp Y0shR94qѴ-:gu + νs.Uq}v4gs =sUyЗǙس^ˊ~#n:CV2^q߻Z OϘGֈ.c E̺hUC"`~_Ddї%lv\)lgeQQ<~T&n}l䧹\7ڎÖy$(|x=~?׏0ys FuRG?:7TV^($V7r92҂!"RmB3""XM8媿7p{y<|R#mq/;w"`I*=dBV q\]I+"[Ddиc gͥם89<\FFmc8]u}:ԃK(ek1CJf 4ląWnˡi򒂋l-ToedY,]csdFMj8oB"dl'pO8a^JΤqF|,ecg|ޛV\U^!b_E8ɀ;- &͛b_-ӭ$7$P6x*W>}DjenY_~)D 1WT""{xg_'s]'?ш n]Iïe+mhPa!^`b^9U"">EDvO.. [u3st#ˡC'yytm-:t)wпMBi~we}EwBә0:l +913 :D`X>{c'>3vrjKqQ,.=zR?|6I|jnHK#)0̶SO" Ha/ɩPvbH0=E(+xӲ""Ii›)UcqmHP4[^IL Ʊ8e%3R),3RIPh= $b-Sy1Ng>ƙ;mSXc%2;@)g*JۥvdT9?9r$ѝ""Rs&J)<-(|jQ~6J(ڴC ""Rn=QB8 n4D(Z]޶o!R\a7\=n0̞sj˵+|~-""-BTFDDDD$)6RUZq\7DD꠸,B|~;W9_]DDcWUٛvAUZQ?pHMp̬UWn]; ./Yjּ%˖,5@ /9M88DU..""""R;jAܞ%wbPDDDDD-ZҮc..""""R;jk[!uOlDL]DDDDD}"""""""""""G!"""""""""""{"""""""""""G!"""""""""""{PiHmEDDDDʦijr޵6mbْúPDDDDD~%*})ԎfEE05HR/Xb9rZ\F]DDDD$ǃ,BlڸVSCYS^'4"""""kg=e"1:5^h$Z|vڵQJg2"""""O]DDDDDE]M%""""EDDDD:q[U""SzfwbHomGDD:v_ȴ^&7CXcUW ry̽$ƄGpR]n%N|y z#.ɜr˿#y%""q)~:9Ky<GF-8Kt2]&F},/>/5wWCEӹwΥt9Ͽ6}< hݡ;'y&}[0-ya4;2t""w)@YF}7xgXPYk:q ܇6iUT+vFjT<lkxGwd==`r.g iߺ'/b+x$Mۼ|s_zw?_NaF+:wF'pDg)?_/}=aa(a.C`M?g.\ n4YWt#qw4c!O9+{z-DDq[0:>|wْOLeLj.Cf0{Z'T!\mGae-+~^K0-. x }!~[*J""{""%sS! t>Ybxs'ry[ƐENM}31k,rZ;6gmHgBKx~ګ4LõҌzP;y vIhޫ Ϛ =3ΚJ┧a#4AboWlrP8JΦoO3<r2³4Ywb0.foI dc3&l(WDŽrcлsZжsW38ӶfB7:%.VZؖի:pq? z^w /s5iQ0ٱ?kq[P5[DdO(۷۱~X#Nm |3ԳrMqf |UrDs𕌽s$)yzxXSڤ ӹ&N7S/- _{u_ŊiVr&3n׍泟g29og$≖.])5݃Ce '""UPn.S^Г:%R*)Q!-zx =`??nnWs-02ťmD[LҀg1isd3v1Tjg38KgL[भK.Yoo. +J4jѺ~=9<.?}1pt[U lh6 ;^̠rtFǩG$"",n:yםɼm: xUvScN׊?N җ繟e?{qX if7x=3F+=J`.$q+!`gΜړ;fyLx*E9G 8-MhDW xi)LhD"nQOXu;/ ضx~jd؟^@%^>/u'S4b0V+$rN^ƴ;0m-\ɱIʠg=[M>"|cx[ #1%v";9ap>wóF1Y8SJQDDZ!t$ 0O:)\c'09x7wk-] k?`j3sIqJ @gkf}GХM(!TP1l-(ؤbȘ"V~>oϸ_oaY$nK[ZD$N(H&h%k7ʹ:;ÙPyE[v(ܸ۵$XKƵlO|9\ nuٻr?[uq׃ƮH*Ⱦ"n:lfsхcL`޲Uc 2֛Y=6:"~r ց a(kemv!TÎ]xtCɅ WRxvNȜK,3[:HSn7ng"ɗDffZe!LqYE0>_W6dh딣K IDAT>>)9#L;)D(qƼ)8}6ilq)7'g*|fwY$g{vx'@@Nǭ\=krǘciP>sz 6P"֍$""7ױB,J6~[z9bp[ 9~7cU,5^t#O6+)%^^I'^{m-vQ1ȕWObݫ-ڼ&ќD&DD.vsb?AuP~-;“ْ wM, !8c~5oMB!|gy!8mv%NoN40XOH[TQ2{_θO/'xVټ@o-׾1n>+zd]}v*9m,;g vfy4r yEt,+BZVpMwԸS).,纸Tz)GUx,</ yvs/ |]Hg0Ft%H{^~e1VGSi֦=kBH+PDDRn:$^̇a/?ce$V8i<ҷ-^g8-w?orHJ)};;&x#z} 9ݺs> k 屧oì:utnEq ⍑k`ˢh#/&ftڤCssÃs%vu""nmۍtdk)b ?>[ԣsat-Uu]1HDdPER\T%K0{AMlR2_}R""R $gP #׵ŔDq-^,v=΁%"?.t{rq]jOۡK)G !"RD(ڴf|bҮtv-JSm 6m]`l&%Ż>hh>! _FDDvR.8ˡG)+T`n8a ;pJ(̯&ͼ\=k2'6PmTGY8b"ˎm;D^6Q+G2ٍ$s:+q(^o\ODDDDNpl_|v8g5з >GK=[CJZXg,2gU}yp̬UWnw^@@BNe ſ?2{!DDDDDDDDDDDdPBDDDDDDDDDDD!DDDDDDDDDDDdPBDDDDDDDDDDD_m:y?/g DH'MhyvkW3{m"IJ%_šu9|C..""""R;jk[\!~^Nzz4 k{8"""""uNJzVXN1Qn=5 . iI= :-99H뫜.""""RvA\ Fz}cj{("""""u#V9_]DDDDv,ǃBDDDDDDDDDDD}qy'JDDDD$)H5S."2q렇iv,/nKoojNy̽Rn_c£pR}a6<wuvxz뵏2z$&Z`/GB̺?k1zrYgʦm^/λ/0;u8YP\&_;Л\ \PvPQt}?+ngH/k]>7x{ruJ^3^tl3q[BDd4@Qqtز?#S;Z:݅6|< 3>F$%)fOH=rM"Ry,|~3uhn:S/` [ VT)$lÀKDJ8!L&-S ߋG7sZ?g7%x K<ϭW|9m+"*n7CyL2)#3'>W`Tu= R4>!ݎK:`|̣,1Ǐ$m ""{CCvBo~mO\P.0"xl˕10e ^|w?Ct<.ܓ$ SS"ڳXq.#ڱO;{dU;C0#TlN;X!ZD$(H]TҚ2u ъŃ4F>MDm\,rZ;6klg)ԛ+GNfP02jY6HMM×Ŋu)`٢$q*m""FeKLUS^'tO!R\mC㳼@di"JΤqFˆfF1˹ ::M GgظN>b,"".nFG &n3jͼA~pt.RHOJ0ɏe\La <*1'k˟n HϙgpdF ""vC ;yۦ% 0KDnRn2u|OjDrbAl{xcϞs0VC(|b~|~^}aʈ5UenbƁӮbħ1CRw *gp2hY搋LSm1 G+DHofq̹=> u G;Ny,ǩG]U""{Il҃Acz3dL!+?oϸշ0e&[z5k-6C~n>waBC)k#ɷart,cSj3N`r1=9DDdW(H]RfB`\/sWٔOpF.!7~^ͽs̙<3;)s^-ޜwO3;g˪lX2Zqޟ$[Xz:-ʭkojz `,pe;6tl$BDxv%ѹ]S9 Xҥ{~~/ndc-vRXB!Eϙ07 +ф${b)sodbJ [p`/wy00em/$1BD$h,"IqgZWRS6U}LmP:KM}0~`' {mNmOnJs/J°v wi&E5)'sz#nWeY Igڗ=x;{fp Ҍx3mkf޻IRLDWh %;XrmE<33l>#FMpکnBD$bEnBG đF+x㙟yI lS7tt<2%1jLt-n'G6bjcB0^ƪX|ctҮS7]ן0""IH}'o.Ns.79TL* j~ /^dg0z0f;sU]4&?KgwO{|:<3֬3]I$[̼kW0M]M}3eq|81yd$<_!.LqQ'ql0\ݙ<o?4&4xrcxIt+={,H]t8׮WG1we>_ټ:kVmGծlN8vlXfP Xw,I  hh 2m8l~<^6q b0=˖qP(.S/X"61ҫ,L3D VJDDjM?U+nRZ,TCayȘ2Et Æ bހ7-6w7OY!61F Ppc`wk'XpEs{x箛i\nW|r(8l N]%=yŧ lQ18v ,̠K \Um7hk؂< W+@Av>e?+4L%[$s7oO֋Δ#>%"{p;j@m;X<<\Xbz:V"[ Qȱ ̼a0 b|`^x.ٸ~[*e0Bck`R>X9ĉ8 ;;`۔}( ny˲cGsg) AhH<g+Wrs u]Oݲ ïILg> 5-c+kɶήk^ 0(y13XkL??//޶#v t:Їō>/ n2_=vC'ʴ_ߋj+V(c#r6-;va;vTL/""P&!,D^qE197ӻ =}gnwb n=!o~ك;E=EyƻG_Τ/'m≥@nll6\ܱ`X8p 﫹<Vc8dǴIL߂ݬ_:ް 3uŁfpXnY37y63j ލmBټ(]qj>z.=0\ߍtj"08G DDE|\Y-Pyc7>*L?vKUL/""F&!t<zLj #Eٰ+@˟Wp:+1E һڰ>/obo0eM 0-vK=e˳?z<˄v-,k,^#{] Z&Tf>^\ՙ{n9 p\t'K.{_o 3l@b8,r/sM+Gޘvȟ%`XStp_ߧ#Ѧѫ7_e֌\hяYm&f8 ͆1uG\[ |bZmYijep>$CeZ/ODDh("ma>6.xie~ %lG܍kj3&~Ɯ箷:y5g=7m9f}\vpBY?_AFs i1hz8Gk,^ITP&\1-\9.{.d k.eεnEDFElBYi_yVP8v~?6YiR}h=w>3Kvub4|;Ǿn^oلP^#e[-v޺N>xu qdZ h/ei9Z_.U_ad=s{ncLI-AA|ZUXnx=zgbmgmwc`&,хxxٛ IDATn`҇SxDz~Y' /:(nߓ# R:Wğ]fE$311}7o'V[;eR,˱pp8bx{mx-ڢ:-1A~t&s̘9'&pꭃ醙\NgӋH $"RX>uK ;懯OA8cO>ߞ%pU(HϰF2jpβF # i9;20јV.@![>xLs3 Z2{=xfuwI% ioextBru-VpL"m+XFO_}{y /TVxn`ELf]p`68 YvͼrZ2P2n""~T yєFNV:KZ{s- sp\喏9+߆OX5&L;{bdwo7w M5/?w.1 ;S:YXV^DDj^&!tDz4)+fiF(l#y?.: S ~h:v=Llȱ )doIĪ^W9.&Nr2 YA%uX tLFG@8XU}&sdI^q?CMmDtodPuY3Z3|{%52>3w߀G]Qa9-d搆n[A8 bd|=P5G!b9"{aqp\E`1``f{T;&<Pҽ,Y$l g+Kav(0d!7Sö&\U@"0($O +g;|QЯ/6&аLo"u C>yx ,Rz[dYem81< ,BUrJTlKط>yVL 4w;rCKe޲BSrMyk|[#7gƭ{ VϖUzتXVex|9;[\rsJK^ABf0i0Bv?NTTTTo9ʱ.Abl 6)FL4UmNlsvcae$7?\_YT\'8:P^EEE%J;!DD?fpЇhnc"zB_ȢmItnהFqNֳtߋfUvĉ:KM}0~`' $}6I!ܮ66c #b]Iwn26ؤh=dnw"S-f1ݼ;ϽʮF*[.fYX Igڗ=x{Ἃ֥f,e޻IR0n/k sL ?ߔٷe4j(׷r}cUh("1yޞ85p%5IRַ ͛WZ2NcL4=D^M撇3I[|tg|S-^1oq7/'jX[>eO!ζpu>Zfw1~vҡw: ,* 0|<""R"6 ÁW` ĥO剅=4~o<?3iޝa/ 1]h"^xEvi١lN 3F䇙޻r=t^}5fLٍYgIL?F̼kWNMǃ41xkU+XnNnc n'>`xvdҌF-!?tmg3yp?w4&4xrϏc$Uq$<ԕ:>T[njA'-)ͳY9&{e\OeC j{n$gxNۖ3bۇtGf }iсG{Us;iBSqutʭeY>`WL/""5WϪ__^~ܕ|ugjY2]-xllbj+""r M3\w6EwƬ""r~/IɩNW."{^D8\ "2 Ѳu;6_iY\.쎈즈T U.¡ͺp(W%=K^)tGG!?}m;mڴs_BWBqH8ҘEls^ub#gEDDDD:>) !"""""""""""5BIJBHPBDDDDDDDDDDDj;p(l!;k?`"""""Ro8Q$&ТuqشzbHۮl^."2 6L@a#""""R5hŎm[h֮#"""""uTD";k?ؘH&ay'D0nw`YVmwEDDDD޲;ay'}y' BDDDDDDDDDDN;!,.f?j/o 6LM=;'@EEEE p &)'f2 ͍Q29[oK}Nolapحc=L 02_ǡwm E'Nx6D{Yq%axjZ>XVesm:qtE_{ [x =")"""""""q"TR"R8pآrnφp37sJbY"u1wMN7^=BwBL~Ԫzo+7ͬl!YFxj]H𛽜9i}92Ê'@@(:>MB4?6⒒IMI0Rh~8>[4 CXg*6]Cwa|rk_2a)_ɤg@8w#o}_^ pcNjsLv5g͝6|ǜ f}\պe)ЁxҠss i1hz8Gk,^ITP&Lǀ.Yx.d k/ed7zM^`ⶲ5n7eķbف WϞm~MYheY0 3!L u/!ލ-J}L̰QwBoUTTTw0ÄC!B~?6DVrlvCMy` oBW.W۟~+ '>;;f?63xqm͉pⰕap[I|?3O2y <07m]o{䛴KGzb&O:?z-#[>e&OcG G1jm-{Q΢w#eؠN:?bX%}CA~~R&2ٶm[q}=FTTTTj"NKxD^KNr+!l<'oϒKYgذAєFNVV:KeQ^{snc6|mq~T}Ϸf?L;{bdwm\;r Rm&З?/s3\0S2,,+L˔!(PlYw҆Ox1Y ^[m)p5G )( ‡Yxe=pD='@=Ŵ^;yeL>S ͊U~⩃0釦3m``f,PhG+_+#2d|;f[Xx!7Sl>[*yaшx@~7!K\@snb=m;{e<5d[~V|zx m:2ӾA21LZtJ4Zv:8硅ҰqLV@""""""""rMBN_,,l$4La47k+v2b|< )=F3wbvoTZ~I)8wmgפdi`ۅ ?P|()m ՉML!&n$`p ))UnUYV{$A0M!?~`?csqT{?dKl:uYl3']NAy%776]h6a9Czo;3ʚ6bh4 """"""""G,rBHeal{~<'K:_oHI#OϤqzw^6bdm/m*9s gzF t|*]tW ]X4/<";Ѓg6KV<~CwB1<$ESDDDDDDD$'xVUr578<;W[gꕴۢM+~A-؄x| mN8vlXfPĴkɦ0`':ѡ< Ch\1D9lXf@a` g,8lfpA6Gl!ױmUp Gq_ʳc#`":ƅa0p%Ui('HuOG󋈈HsNUj5WѭWcqSwBH}0 M?9 zU7czdŸwVo涂Tl0ru^ C˰* {)9CcU۪t9drV- V񽈈MB(!""""""""""REdp#{"""""B8tv7DDDDDv(w"""""Rc~/Iɩ "V۱iZLrawDd7EDDDD~¡~_."~n~"""""Riӎ{v7DDDDD$@GDDDDDDDDDDwBHݧ$%!DDDDDDDDDDDF( !"""""""""""5BIJBHpւܿ-"""""""""""A$!_'!p)"""""""""""@$%!DDDDDDDDDDDF( !"""""""""""5BIJBHPBDDDDDDDDDDDj"""""""""""R#$%!DDDDDDDDDDDF( !"""""""""""5BIJBHPBDDDDDDDDDDDj"""""""""""R#$%!DDDDDDDDDDDF( !"""""""""""5BIJBHPBDDDDDDDDDDDj"""""""""""R#$%!DDDDDDDDDDDF( !"""""""""""5BIJBHPBDDDDDDDDDDDj"""""""""""R#c!l!;k?`x,N93Zn{Tiߎ+Vi&|>_ LLLL ۷gȐ!G5ƩO4F.8@TS q0ɅU\v 8䌛@bb2)M7k'y٤gt9Rv$$$pYgpDʼ{x<Ǝ{D5N6hJ@TS 4N.8qfJ2vz;-Fl!C\B.F!2!iJm:qb 48N=)Mtta8ڤq*NcTS 4N.8HJB㘲ޡ&!RX7۶fƩԦ#6msXuz&Rv~R4N%iJ]q*uƩR8=j`Y$ƩԦ#>STjƩ&StRhJ]q*uƩG:N12yRhs5Щ] 4N.RhJ]q*NcTS 4N.8F$"""""""""""W?IטKq*"""""""""rtnWS tRhJ@TS 4N>DDDDDDDDDDDFqL"ƩȱWIە@Tݢ)uiEVsJĈ?̥N#[٪.{[hJ@TS 4N>wB"Jy쳥ҡ[_F\pscT7yϞ}SY~re73ow (w m:iaԩmIT]˲U߱aErtBƲvso Q7Ү?lxJzu\"˞aW-p=[2͜xqVZGe><]6!zeDZuh;Y};QGPG$"xٺ)#7}6m퇟C03yxkY2º IDATJ"?d٧߲.3grȓ[qbez,^)XiN:_%$>wO)C9_k4H#t .fOtdy{ .Cn0;"]%;;Eo-Ikٲ:vuVw(K݁Ő[pcx@>{6bܛX LqBenL;U-x KOi  ӎtG~ՠ\7^n=#n>X 9M ftیwVc4ږB8=q.Nժª1b[XG; wΈTd:s h[NlCHbgn>IX~ VB"@ױS\" ONIJ@HfpL[ObK㘎0{֮bcuzWcBwa}Wg1 Wc@ ?{ 3(/&0𯝸G۲?zZ.{gZ?v ҡ}:˖[w駑ذ>8Lj #f:##'>OrEۭ4y cZim;f *S3lRtga g_~>^|]vzV"R"9.'Nƕty786 [lJ^ {u:Ihp-/ݷ!m_[d}I̧~gqiOo|ngvOlO9 gZ^l'sկzh.}H_!kAwZĕm]ELj<5К/gS\g!\8q|̯?ݕkْEr&)cEoԳ{H%f0TRStD&`g՗3EɩjDʳNjm}=ǹ(,n~אjb&>of{0ID@d:wB6R;<$& Nhl%Vޘ ? YR9f|'.rƛD;mxw㖆!weXN$zr~yJdz^}eiYa1R2ӼC&[_UEij/mK=f`&,U9x.q5stYܣRߞhҟ cwWpSRVQR b%ugCqy)6[No;X;bI nヹ/.1k$ZV`'+63FwfKQp n{q'ʇ7sv=@*moZ+ڵ'B6&ia*.cת2d];|\=Վcx\θJFM<مc߿Ǒv9J^ ])1ymXs4FRf-fm:{霜@?xk &),uYQ9s06IOi g;SN3+MD zRc>ӊJψUV8d Ք(_^%3 `p,")(m ‡Yxem[aH;V&yޕGбdJ8H=Om1zAG,lj+|NNkF"N LyVI\~fDMNϧ35˳zk:h6swb7[9Hkͣ银vbI-FO?t mfͺD^׼ Ϯ K84U3|5Վc+3oHJjMAv}Sn mTьpz| =^gEBs{ǚym7falS…͔Εck g3``K︉tN/H1CVOt~\´('ck5W);N+U8mFSwkڛ፫ k:5&9\䚳?ŏ''A'so?|݄&$͡!761:1! *퓋?Ҥi<[fٺݜ2M HDpbp:O`ĨoM8cf>}i=fQl g#+W7ֿPᬜw܀yoSa`Go~Ɖնݺ'6Dk}4[䔸y6y;&W&ouoGuq u Yf]ʼn] יcⲬFa_.b&)=ʼnWcLL|}qxWy'YɦG~ 9.Þ~*v/5Th Ga6J anW`3ojYHpؽtf㙲u=v?owq-}1qoHxs><MVaʄ

}9r4FtLWH 8"goDԺJIӶq v 3! VJ39}H!$i~l_&Oy煷۵/?m4'I8~{|l1o1Ю4/b듪fɓ;'|OҭW[HHLqcV$H( wI8f`i#ɟe rI%q+" cYZsE+SW_}ŬYjmhH:4|uSS;N܇rPDDDDDDDv4-;>f):)EDDDDDDDjIRCqm֟dSNxLJ;F>X! ҷO@8 NDDDDDDDv4-;>;y JAq;n23ؾ#Yq w`ׯqOӥK<3iiÇ#3#1ӌ}v^ܶt}?"crprJ[QRRC(ˁN9""""""""RO6ް[vme.U5=\ ȢˊbZ&eb&PZqޭG}`} ec&?hRXXĺuez8EsxfU-ao]ĝ]G}584."""""""5jcZcrСCGoYʻoEKC.ߜ:iӷfƥXh"FˬFQj ma6mMoXd?VARV}_QyV 6lruV>ڑ¶mHIaү1J|y Igsεgd5sR,g}7k׮9V1W^ϯ{׾Ѱ8>Uq{Ln8'6ffi>ZSc橈_C/-ksr5Wq&sW]΃E==qIyXzꨃTMf'g9?rs8g|??rs>.2Ͻ)!G,͚Ck^*|mǿ}>:tFuAqUWajXlZolM([sޱ7^|?[`&+=syINbn,ߏo>cE#cOY/'p#Lii8v#sR^[I?P- :8.v A'/7nW>cҰM .>0zgC0Γ&c: m]NěeFŻ0x%9^[[|sZanv1˞[ԗ9LgH ؼt+:OOG=6t@.h+O<|SC+"""""""rhHSUy$N820(Ͻwyw^uϲ- {yg0 {=z4k/,O?03lЋMiV 5wX [&po=7>GKy}2JhQENm;tngٚ|2R=fOu.>1p]WKC+Һќv|ڤgؓWZk8VrG3x3vV<8]=?LFN9y;б&ם5vy/F'Ǡvt9 ;5-%ߩŊNJߎ[N= ΗA@J"(6VR&]( F:4|hΛ>^1=[݇Snљ"|}rcrȎiƯew{߳=Z[ظkƏ8V;||sgSQ55" N/s S>BjY?~8gϰ9<G|&L꨿96p)A _f[KnBx?)زu󿟿^&3XXLsJrR"zר*0pp$c4v(^K$tc1Fk BS5XFM8 ^1s9<ʻx},cr/watԑߝs)i|\Hǭ[tɂ>#]1HN&d=[ zW[)޾I1Øv$:vY\B)+ۑѨlqOmc[ S-!lJvl?\0=\Qcň> X`>ξgIigw|X;œ\ 6q}^JIXU=[ UmJ0ԻO,Kā4{G =wȡZ(i[o@AVR0`b>o|g2EWHͥczi k?^ 73'/vSXZ)o/~Aas;/,;IA0b:kYP6D3"Iƅ7v:odN5o?#Ybn7}sѩ(mى?WM)3Af3찣ƴ̽Ȼj=-7aD"Q&˗ߟJNN;~1v,G<~}Ggt|k>%c׼2x`Ҳ*> YW{+9$WaƵl:t@-[Iؖ4#Xm~NjN_qn$m]Qt(:V`'fYs朻ər/9^\ٷ楜S7qwhKa~YgVLnd~8SO~is4W_ʿn,h.\fm ;CщiOcps 20!3 h3d#:0vÍX\_.YRgswN:tLpşq}`U˪fRZo'$v>̾{25"o|L sfmaa0*6kTwFbϯ}Wid̅7M̳n>I{w"7ҥpn\.ǎA~~>Çsݷm̘3dӎͤfV0S8'~&gM X=h&g^ΣO$qbw6-䉷9>$_VyK#V.D#GwO[Kޥ$Jر}9Ix*}owϷnFvWyc)~* h&&'uB7M0$.q^xwwmOBw~2ɢoZxXμyx`'5i """"""""4l˛7pPb7Y"/"h!<>|D<..1#!¡(;_ۅcD6%aILM#,8hb}$lbJc')D7VҐ]{ Ý@bǍmsKRF F@U?O2)"EE $zaJ_ptߘ7öJ E,Z9cg]1xtʕ\3z̗]V`e./U~"DMK )ML$1nп}MRQr%O1K(*kYVz_Z*H%?d/bUlOI3@z1fBB+TDQSkABfzzU<<M';8 XǨgU9Բ󢄊*-I PbUbԄ_SmdTGZĮ;E %(MqMKI%?'YYٕ6~.ϭ\QQ!III e'L"`nii:rߚx<ټe ׋vanﱖΉu]$\%k/~$Dp2u> NDDDDDDD5-;>c_|~SkpHO'j{%WB?ُ?K)#v8|D:Bx).lP @4^}刈HT?iZw|4 {wq_h1I3c)ɏqOm Q\RJ9("""""""R;Oks,c'堈HT?iZw|(SlǤS/rPDDDDDDDv4-;>fɵ' """"""""""".Bx<^,ˌrL[g;`7"""""""rPq^k|4e01ef& O0r deraW9p~8T5>+!:vF PBiI U(wi(-&ҡs:+맡q'FP\c~c}7KXx%.]wzWOC*"""""""OUGSz(-YTK0xبFOK>YH+)#uDDDDDDDDDDDE -BH\"%4\DDDDDDDDDDDd?F"xFk!2(-*jWRRHzfVOmrڳm&wn'"""""""""""-U4!6vlBvOϾv!+[6o`1Ƙ41KzF4^IviH""""""""""""r`"D?ed<'"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""r@z.,D-УIENDB`AntiMicroX-antimicrox-b300273/other/appdata/screenshots/calibration.png000066400000000000000000001355411471077622000262530ustar00rootroot00000000000000PNG  IHDRifsBIT|dtEXtSoftwaregnome-screenshot> IDATxyx\e93dkfot/KKP@Y(# ࣠* *࣢ ( ȎVZNfscfiڦm3|^ו˙3g$sd> """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""+O  BЙP0?ò.LDDDDDDDd3DX,X,vO"X'PVVv}qq)@ '3ƐNX7ێH3O{VTT,LRV*uݝ\DDDDDDDDvȲ,,"̦My0deee_)--=lQ,4Ƙ].^DDDDDDDDv8$Iu]ײX,H?' .:u {]$""""""""'NSTTTJis`2T#"""""""D"aB3GŸP(t4/ocm఑?ǶiƘ+MDDDDDDDDFeYA7}$(,u]M˲bDDDDDDDD5~vf}jċoegZ(#~sJ#KRlɱy.=!ӻ1gOF:>WE`LP#"""""""2.͑Sz Y.?Q2""""""""22*8Ԓ('F?"""2.@q^;ԋsVs9{Jv!}rw٦ڃu??S)xKS֣O?@yQC)"""ϋ/ݟpƔ?MW3ڷ3} 'GG&aۿ{1n608@$sDc1bX}jNS~',sᜣm """mҥnPbSqѭX.[g?ʪ-Yr E#(%ۆ4?ȅW{M%i_ C;.P{^|.j#{;\G?/=# m|-8vp㟹 ~T\rtDDDd m7m-ۆSsG-QJpi,_6gx%k~Oj缯^#=E~T"x?-_>i[$>s-,+ n| ^R;,o}s)e?ar7pZ~ܻ\p@hk(G//"""c w5GDDD`YX0?o~Ϥsxg6,.O|/9Rl\9& `HMξ4%9}aO)u\15<' Vp4~ ID͹Ary;õ\{}wukF_8y^?]<G|Ҽxm.W8K9m  8ywc3i_{ x?"""Xx#mCovW9Og}l8?m5+嶱bE+f)ZзFPc4`v$He3 Q֭i5t٦t4 $kWo}JMv]0\ű~x#,fjœ:QcS` ?gPcڔ/P#"""H7p;<.9Un|9EQW+f/ e5[k{ьm[ǭbf(rޢm$cG3Is]z:;ISӰ^ -!Ysݾƥ{SIf>9?Y9=JvPװN6;cp焁K[6zl]t)<|G.?"""[—XUs<'<*,ᠣ1 1(4y8/Yë;͔{ʊ9O?? o;`cc i/?/;#/q7~ H>'t$M'CVyB okv{y;˱`nj_"""""""" LᏈGDDDDDDDdS#"""""""2)L`H$Ʋ#JKKDz #OӾDDDDDDDD&0?"""""""" LᏈGDDDDDDDdS#"""""""2)L` DDDDDDDD&0hߦx+9 n omlCm e=gV2 ܾێx;ma,줍<|$[P\\̴iӼ.EDDDDDd܌z/Vit0Mڟ 88t s{7c()-ٽ2] _ʇ?Ǘen~i&T /c~"""""2z#sIӤR)Ry)4/6*1˵'dhV>?2< RP2sFlvl|/3= /-UN=L&hrې:3mHRBA}IyB]!:nJ~>""""""2z-3i֙u%ڰN0(8R> u+/壨"ҁ4ђV=Æt SbSh5F"""""" D"jz  'ץJSvM#O)n+DaȔiz\ /v.EJ"SDDDDDDvŸ,EXSXu s)MSTS"9  q|́f},-j?:HّلB.""""""9IObmp-yI1f) `j9ffTJew̴Wb` 0K 77ogVtBJ'ttvZ{ 3`dB -(1ݸ3]8h`Yhc 2+9"Ojܢ' qu%.T jdF C,:VuPVV6i49ݿ =a&|LC+""""""Lq<9FǹҡF?9"J7̃\2u 悹[㝧ޡBöq\DDDDDDr4%ؐڐ }7AQẢH$BThlo\fS!Zh&83w_Ϊn +\,* ~,2#}sOsyTjԂ|fyd& 7b xl07 *DdkܥgcXr5,#ui s`.3tK|z_=UEDDDDDd2ȟ1ÿM0|O4৏sCcqt*tu3 +#74fͰuF2D_I}|Cu:J d՟֒ӒK4g^E羝8:P9}}f1v%냚m{q~: XMfe0nHൟFe{%  w^A~3|̩-#dt~snߺMҀ fj{aRq FY*8p0R2u4LCgt:Mwg79T ,}gV|3‚m6$"""""jQq}mP63+jPEIeS:kbo FQs3wcY9n ״P'47Ec|`2KïQ9ڐ> wMMiic\E,U~y:1BN+_yv\thY\8y3)Hp_='~F[>GOuA  ~[y?#7so@O(Yf-#rpsڐ>%` }ͦobj8\rwOd3Ʉ+^`#OvoﱯEDDDDDʷVs؁|3/.0~-zfRĖ *Ku7)nV? mt*M2I9J^ݷ14πl2}}{TMn?٠hk%T!/L?ɜh΍^bښ&""""t%]kyGfٺt$\kyk@3y_JNds-췿_z/?W hӯs~5ί\FJ}u:ޮ{!O!< ~x$b1 p$s(6zMx5òe.1O棧_ȭmϟHv[6x'-Í R, :˭ M?~ 8|.S^w^<0d{ȹ̡2&h4J8 ͡V?`247ozTY3o^P0@c[]ʨ*.fU\S+xko>OKޘ" ,O.!fydz<|6]YճdR wqh@60r lN2DgEy'/ZH?߻EDDDDd,8:Ξ+ԙ$XkcALiX{[t²-44=r:'\ Z~*]S2~WdHk.Xޓ.ekdz$ S\{3p_;d@N@fi9yQZ2\ץɬ6޷mQfI7ۧSW]}"""""2b&z޳?|(-v4wpO1_Ek/\gկm\cS0-|b=Ze6>t+M_<.񽊵9n6WIڗPn~x-r-;aDpuuuHݸq#ӦM%ߎMCVjj R6{OgQ"+ip^|yKe046|dϢbxRX c&5JDDDDD&uh?RXH?K!5%E4I , ~ * h>b97oxU?;J&0Kt>8wۦeSeLXD^#7^?`[^ǣDDDDDDdW)ŠM O7Js/uihxinĹ:GF 5櫆UٔɫDDDDDDd(`0o#Z,-te^+1mhy]n%|H7sa5aϪ*ׄ'HJWU> ^k͛ϛr2`&Cx0,"[_NIS?lфIlMc,^}gl^ݮ9VYJDDDDDDFh҇?BXaH󪪱e}ҢMJWWfQLo2'ڏix[D?8 )!g3.MoR&p$sm6zޞxl27tveDDDDDh4NmPRR2H z֐৔NH{3ݡbP1㼮d}7&^C]l),,Rd0mmmL:u\;)ßU*OLbLsthI(klĽb'W{hl25vOv4d IDAT?DDDDD&. tttx]lC(2#s$:=~ʁ\ǠKCGYV̥Mf\y&>CIݬN*I+߸#3n{s{`0H4jXFS}}}v$nܸiӦ^Uc$&(9}TEL৏}M݃uVW8c /ץP˦(Psd֢Z}ׁp81&kQ"""""*S[nwQGOz\ 4wH]]nqݺu;<ФqV܇̊E`ΕM&yƉHm^ʰ]NNyUHȟ1.o|y@2AOGtJrV27 '{]d>[M+UE"""""}P:ymSI =,*K4wj `.SE!k Vsk<,JDDDDD[5ގMĠyUQu%9uS+6$˔m6g%Y_UE"""""}P.iJ6{x/fɀ@g%*heF'qf51~񍞕$""""2sίW>TePV9|rñzDӾFI,cCiJ`g%厓!!L#K. K$&4Nt7AGa⓷{٦3̚իY6(8>w=\L s miΓds?#Nӽ$|_Ҁe7|Bok:@AW 9֯p|jocyOg@?ΗW4]x:ϯ ~20zN&[E~" V<#̸_VI.wWrG2gmO0Ѵݴ޿@MxwV-M*IS{b5b![#⬷OEDDDDd$YjzJ>  vgW^_I ~z\Ջy~~gm+[9Ӌ:y_?my73'g;˜cλxvxM N/5͘4xYI9͹ҡ3z]JVkni\gTl5'jB LDDDDdBN<ۋ7rML<(. .\?¯~ oYK{%ѹ^_N[r\\#h2SX ~jKy[{ԟal= ?),+ӫ]wdc#?o'\0+G w L&$kakAוYd>}9<+GDDDDd":vGwz_\NF_l+ɋw9\at,_/vsl=]wd ~ʍH>Tyd{n1;.#k{8ϵYd2U00,xD=W"5cf8ʩ..%dU\x퇙s=˝wŝw޵S$;9@V}Dl2RC[Q5RN$!U$|V_"oGh~@L acY,[$uK8v^xcmSyks O;/=߾Jהy̳_=k~΍wVsgq[5/wl rrO$yF3Mct S:ܢJNcO#5|f IR$""""2Qltk=e9棟/cg|u!38Yy_O߁ǥi6zYHҴ/*gŸuu3(Iù¡16b1u%X!P|ȰY9"""""LӾ}rr8W4xXdr$| וxjs t?YU5""""""JӾ#SK6X ""cν̥2#w\a6`sGqGv~Ƿ^7ѷpuuu72mڴݫO8&0ľ'G|Qr=S+p^|q=f^oIkxJ/]~̠:PۇcF%""""-AKH$iJJvdKsssuv_֎q]= 894&ԯN̾Fx3=7'֧{VH.2e XX,^#p]xlZ?9?7u7^*#c2ʺ𧧧^Glϰiu%cum+el 7$"uϚqQ<*F^i1ռSYјBd}#\Zk=+GDDDDD$e7H,BbfVZ6A,M$1ը)_٤+U "U՘L58W84Ne߻q绰Jd Fc <+GDDDDD$dMMDWtkO o1 \ݳN=Wِ DDDDDDFSք?Vc0M-^1$DNJ59ưpWՈ䔬8ݷ&/\{&VF̕Z+k 7Ċb$I/+ Y[FE8z]ɨi؊TOcp V{VH̋cSKm/YU2bg@WkWN҂LONV3kE^Md%ŸHIPw񋋋_3}fCϫkm| >kȋMmHnh6Q[Q;U Ǔċ[G9AfT`OǷ~1H4w5{]Ni4\{&,_԰f/ I-pO-ʢE,`וbXXW[[M&wD"`וvuu]mSxn!Vbczt_;,GUDDDDD$Ky#=y5w}ੱTvsCc$7V] q>Q?YIîq kW^ - KNQ#"""""2OOKo mg|>UNcZ4ڗhdAhV+;Td/4~i8tuY^W"Dm6TK>=ҤSⁱVDDDDD$gȟXql] *//g쑿7cYؗذ~+={47^W![<S}Xe߭d{ޔ8f ƈLv1 ӣ3B9sx>OuF2B"CKgv7cjԌB˻{* ||}N _? U [8?4g5FDDDDDDyW2?ٽQ?ñmZj+k\I0q;{H_ 0 ]M]L}ka@וLR/M>Ԕ@7D*?pH'ɋqEDDDDD&qՔ*--eثt/6lϳ1=\={#|꟯g~KU=PhtCdM7~5x:F^ PU1~͕C9""""""ո5| $3kG U 4T5T 7488:pj@\Iii֌9 ~_V>jkZRey3ʗHH3qJ(l2.#C:?~78iUU,yy\R]nc}ł^+MΕhф{e"+dQzm)Yxۛ}ϏcS+اa;)ƺ΂6+nCkkg8߳r;ćղḑ${XX -."""""ޘ?$dw贌\STTļy,{jm|'_^W:¢ݓ7v5^^?#ֵvM%iþzﶁJhw]"4O$gztWN}Y;I'qv\.g5RNRSI$JU⋗LVOWQ[D*'@`p#M7Ec&3+vTOjf@nLkL" /Q5""""""'Ww_҇ξ>!r(t߉u{ Ӽ.  $ ȯXlCJi'2@HP?#qs+ Sguk(,l9mfظhV]`QuUNR>@kd4Š)xnOڑŭti}Mw5d uur/qYL:q%Ns oya X0ycdo2 %e_ ]?C=|*VM^@5"7#"""""2 i ,S/lۦ::VwxD^*IL˩m9?r2_a.99n6Nz~_KyYlzysnoa}" Ql2Sy<% @@2w1 Nȕ%GSYYeeeb1HEmm^l[b깷wc;wEa&kx[Xg6oM/?M毆JLPRᏈLZخ=|B!ff3ji&EnfJq^W7VϢ[}iI\!S·uDKlGDDDDD&13F캼<ꩯVmwwal߽vO]-ɖ+o bB @c _MƘЌp7LqM-VԮz63?;uif|<۹ݝ݅yߧMds߻\߻7~<0VB \uH4uOISBZDDDDDg1}SMM NIBͥ55&W _<0aT`S6 #`Pub™ϤQ/,HQd}Y\۟VSHXSbm.x[B IDATE^_s.)k2 =^C:n NxU31͢Ȭ(k8#HDDDDD*Kqʟ;}iWq|>7g~|qqL3%6dN/Γ9kKDyM8UK{ 4xvVR돉He)oFVSl t˩JF];G9㱏Gk!;'iy9Oz\?rʳ9dT'xDDDDDD;E)l{10mMa-he-8{$J`ba]hc'5~Ӳx_W_* fI?Ulpg-;DS(b2mÙGDDDDD*Q+[/Xżyl]B,8m ώV'nw?$f >?Ip3YXNuuuA03?5˗Ք/qڼX^Ae3&8jn!K&.%]}lfIէ8$>l5{ A#"""""H#*H$ᤖx͙V|gf#~7X3?㧳DI:w~wXX,?sƢ3XXAMMMa9A?"""""Ry ^>w6フF;0H4%8Y{)яDX7vGTԥ4~fIc1\9+a~|~#ng$/fNȟV[[˩rjݩ4\3a X?cVus>Ox3o,5u߅S ֻ-y&ͷ7szLֻrHffǜ~H)?3/4B!y ݏvN&>mu46Y.­to| A꽎&Gaf=3JDDDDDd+|3cJhOiil!|'->u-c ¤#4& zIiO/5KDDDDD*MQv[#ʑw>r~uWCg*~ʐ(,?"""""RY[`8.",ohM\=^(q#o:1!cI#DDDDDF%T,cQJ 6]Ʌ^GYGDDDDD*MQG)Oy{1JΟw;rTH%+jŞhuqxCdEedOdhqy=xǓ4:#du^Gc|JSyYyhܤRp1JV6#j:#,lT0?c~N&)n?eׄ.BUgXas2ǒT?nޞS~d=={-|4Sͪ -İg5ʟY? g[д/,Eʎ?YO+{d;Wzf1V:'=9iE}H)eP M*;tgO9htr4KDDDDD*Yw24%*&cȱҴ/`_gI' 4֥ } )i\{먙swM8yk+ﺐ1h|+Km ~n9~= !J妣:)n_~}/-\ZRjuYgT?nNum5#USHuA>:xtϝ}_B!ͧ=370h(### VxIDDDDDd|Lª?~Df A1JV=^ǐcI7mg PESTSn^?A+@1M[YK"""""Ra _;O&YSE }د D=A+P'7msE_'{wM*?vvu%K/` kWu!.5~bi7cr4KDDDDD*Xw}|r==?vc7ϭy6ɤ((叙3/4 c/w޿ۋ`o[c_t?Uo.~ض0dp}c610f3?DDDDDD溢L2߬gBBS&aݬݸ%m>~مڃ?ۗճ|&x5=߹]6c–q4ҭL 5KDDDDD*OQ~nekԹ;.66ȏM,{_x_񃖘;NQ,k޽ *d4GDDDDD*(O ~۞i,tw`ކsuR>ux] Y1|5?xy!878phR___ܠrXA%"""""H#昡!6wnfutE'_hOʵO,g:) 9=l&~❯{ͻPN֏vDjc gIҁ+a{ _1X+ ; >T又T?OPO8޾t w,qÆ{Yٺ!+sZ/ᴵ66;A477w d6'TH)ʕ/뛶 09vlڗֲ=d`?)4pv=,8=# ]7V8lH]A-<`8FHE*Ε;}O&xKwO7ֱſ7rqnvrz땼jΪdOk30z߱ޞ1G?Y '"""""RR2 J 091FݏXu?x?Ogq^8'S?~yﳱj';Ask38MٟAET?KXY0{"ې  ױiCyCl̞Bvz阴S0}93Áau{鹶h(Jkjӕ gSZk*He*3/4yU{9vԃ) L'v.ପ:Q?ܚGqzZJK.N#lƋ_deagTE+fu奝/);pɎ]qEk":]?tvw.?i3~n{9L&NV29d:?mbyblLLLΚkڝ$MboNV]k~N~<ې; \]\up{п:YI>sh/LE $򧯯wƑ~w :Y ^q9'|#kƪ\ҿ ^~בNg]6j뫼:{:q]mi?sZ0[DDDDD*WQA&LTOE3LŬL&ꦧ&l8Td.:>u.,u)elYGg=ׯϚwNڡܺz < d-_DT?2_9IL|s[{߅[iNEs.V(J"꫱`QUr5}1x VN7f4dE-?mZi(pPD*{؟^*_~q}m?w"<<󹇋_bKuG}wN؟8mW6 qZ[,ȏ/sa3st9n[)RTQO7b<3i]:U12I$^K.dr!ϝ7茐XaV:.μaoF?NUi  L2|}ie-`ņN\I6ՒJFNW4gM  EDDDDD;`ldfo^/^*m-mv,IhC:T+ӍlO5O.$>d,OD|=dBء{$|t A3QX pqW  MPur|Ӕ/tE/AF;MԯA&(fS>FE/||j6\ץgh$ WcG7`b폴B>W􏄢KFn'%)  L['MMff^ܳxW$_ w0on.oꦺD,A,:qKF6ӗTϿr!8>d8[ p s3붯d7d=!7D(tcu kg/ 30x [[Xc=}^';f..z?7+Ƨ.]%imt/a;7 9W0tɺܢ5iT&`ɚukعw'tȏ-pz(C#"""""Rfe57d,:22Bh'}7p>S;xdo[A0ciacq6?a^k{Eb$ NwHggH%?V—R1o|w.^"[[fwŹNOטk^r ?[-c9 4̶mk[޽^';Ǘae]DDDDDd\ϟ~ f}(ۺ=d`esou7FSWWOW~&4޴&R)_""""""9WMKV%qr]nֵc 5rq) u: tinhυr*8q 啽c#CCCƚv{gH' `fN7B޵5kװI&ΆXWYV{L-u-7)( K\NF޼HWO;[lMĦ>Š-EDDDDD&Z P__==o_fg3_o9৒y pE~h$ {d#oX+ |X "#*DDDDDDfd䏙5 λ]2{?g ?ĺ¢5ZۻJKM MH>6_Y]{wdͶlۡfVMEDDDDDfJ5dvEi/Pˡ KC}IIKC -1p^Olt~z6wnfdd1LDDDDDdyV;Ӹ\; *:`,ˢ~u9*pw~k[G{]EpbINHsC34_F<N-{""""""yXq_ԯ^ yȻK04ID^8aiRyDJg$nE"∈˲1X3yEJ8?sijl:IAģq9Rv1ZVL$"""""R~%)%"""""r,J*A>ye{qA&c]sc3NBh[h4e"Sr?,&;+_)rI^)[%YAɼ#dv=a+L0:ɬWűϞrmy_S1bWDDDDDDVI?'Nc@*uEk&3^'`x[^)k%[,/'oW;*Mz̗LjjjN2%Lϸ`>a!""""""rh%}uovOm^&<&1f IDAT]cC#\H{15oWzS""""""P1~N`س8CKc1<ڈu6ULiipJ∈%_DQ:`؂ _ ;ݦ.P=PM$0H++,ocښ RUʝn I*yNCS#"""""rʢ?bn@RX`&H8:ᄶ} cΩO Y<#"""""2M&=能rSD(*m{Cihh^'rnA|M^&3ʦX2fj'0)=3PWWuДhŴic<ܳ8""""""sMY?XuuO]2"c6WcPVo1F= / dJ4< . kZeS+y,BkHH1mY=F&M^&*o֕Q]J6qʟ{` N5O2ȜVJk%-yL=HR/{d"@ʺ"KxlԵ`ܬmƧnbgqDDDDDD*͜*Ulo|"Ճ>5żNR6~?H:Ix{pqgDDDDDD*͜*qc;=TҬ,Q9Vhj-|Xꧫikm)4ȍ:g+0U5ν ^');555 uO=w;N*HŚ3n|w-=ac\gВ(\یq9{ LVeΏlp0 3y^*!ڸ1VK} ƭ*I{pN99]9]uLB^')[>Xu ~u!JM2J2'Xn,Ǹ&sXdJ=2X1^"F ?%j FT""""""B?U*-¸=)%vYTUUyUWWcn6/.^iM:djdh 1'U*T@SĦ@ˀU*oW$b޽PZjZ0ot!yѐj*䩨+ỵ_@vs9& \N2g47~R^@y78uȸ۠I""""""%%TSd\o4seY4N2:duȸˠFN U*9J*&-.dy@)-l[Z[1cqsh~r!kZYl.( ?yc\W䶴*Չ3n4h\uŰ:nX宓k?o*cGDDDDDDT^/l䲮" ́Z0`eJ= &""""""ŦE(%rیi`x#xfr8Hܻ?c^ۙ6ѸӠ*5%Jԛl""""""2+Tii$I`^fH-ά,k6hil)564́,%{u.dEv,)yyX>GFr%!\(_xw/5ߘ;V8/sV,}ͳEDDDDDD<"gGϦgMMgx dpBmS-U" ~--%ښ9հ [4Y|!""""""%EWE(pM7o"4'7@XWZ$b޽a}A ^S;},cpDSD@33XBK x&`5Y pg?'⽥*c.rmL/~> ~5bg`3 }4|fFK77r1úҢ5KYCCm(p])}3'{9%v DDDDDDDE39uǩc=cWcj] T)ބq K{<'+}79u?,pu~5 t.k ZZ{91o<]kr]xK ~g9gG UDDDDDDMH" r` L!oC?qA$m^ !B=:o? g϶}z< *IͲ&˄}lH# #~£a#a&o3Q5DlL(sCmnA˴̌ $jx+D  P[C:?j%:pjLLL`:fJ'R9fdBҡ\fK $pA"""""""BO%q?jlM*:%ǜM?f:&T|~|i]S!Ȓ d'96].87?ZŇ"`@:֔I҇]1Rpjq12/gƇ12mb:brL'e9~g6Y_O>8<Ȝb&HjP򧿿h4ʢEu 9>"e(H`0@1N!""""""2a 7F#De͟ @1ZDDDDDDbAǽ!e(#0 \-ӋT00%"""""""2Ta*DDDDDDDD0?""""""""s9L又H^<*DDDco/]ttv7Xlz?1=ݟ?Q= """"eH又qpnAy>[M\mp?: """"%@_KDD8o\]}P%eb(JUS U]{ 6Pea"!UTG3N_(f, mVS|~0ãd_ L\;0c,?BUM514cÌNq ?Zj~ӌ 1Z"U5T}8}]# ঒d\X 5&1R8:Xj`Yj,P#""r̂3izWߛ!dB}:.y7=??n^,AoWΚQ梏sS;>m%99.={5訮FV~EnZDDc.w_Ɨ?/|'|`랸ovvֿ,+?׌16$ ׊8zW|S# Ⳃ?{:Ua.7l玛C=uxwonʝ_\qj/[X]-~ ŷwċcl|[H |,SO9G>^sϲ+X뺸G?ߩC`#83?z(s9oMF}q=-oaDsEY=/'{;z/7ƢZB_1@.]?[墿^?>̫7WLk#B'w>s 4I@/h|km?}^ cj nMq鬋aI$M{\Lv/Kϸd?i]C Mɤ'$JH/H ]}WQ/+. MP KH!)$4ξ_ s]f`.ι"7Gq̲yXe)ݯ Wzs'8*$rr=u]ez,=Qs?bڰRnWcW~;!}ᯨ!뉿ܪGޯa߯[!$oOE^,WJ ,2;SYyroJҬ2m #3EG^ns)#;_Np5?y)U\>>~-_␚˕e5K#Yiڹ;N%iK/QztveSئztv(?k<|dfSDqףLwԜő3ة駃YڶRJrTPRb~f&eLLmճCџRº:0&]]:&etU7}zv\w!|M'KJ7WOo)*8ITt֑*9+cl%ǟ?ݘZG^&\x:ϯUШyID;uQ#{@/Jeu~jO9 .4vD,TE&5>N)rUy.u ջC 57 y~]JjUj oSrga80{4+U=\L[TZezyjoiZ;lJ+R~t3LOT4 umZv); s3+p1_CG/ѺE]^yV]k &~IڦLPڼ[̪0vnAa>ve%׊frwexCO(w-6uw.bUejE qwVp02 j]ppjހOK *}w)tLYf? >tJD?Wjxw}\7Mjo_C￱T;JMMNYS//St:yкsnU͢q{LMԦG{EG6}X_:<柵me3վePC@Tk|58HŦǧ8=Kd Q&`11Ř!ڭTԠazv|׿LD>77K[0۬ZlR}tV??*Qd[4V̲\%," ,4~HyYt'??vְZUW {Rì[٢K˥;wjҍ<\3 x\VP=QF=Pj2ͬ~H)/Ǿ|ArC6lVYPQ;>WoᏵkU_vj oR䄉lSW_IWgJk3D^j1V4]ye[p RwyX=زuk u(sdpѩ-#+[jঞR7+OIY_?QX:m8,u ;zuPOhyf]=CG? r1O;+ݕRr7YuO$Divq=tl*"?Hup2jc1J,j Wo^AJm6cVoIĉ4pM^'?C&|ҬEds*q'z# G o 2jsWWcl];)Cwt)'eNUY'^AL bP=)))|\a5N[H^\."SᏵ~tapWvt8%_󽖩&^>5Vh}`4J. U/̫(iVb{z_yl۷e5EmozXwj"SIMMݮPצ:|`rLjݾ0j]̱J?z5tdOBoޞ[^5g5f>@˚ktOmz_)~ͻUϬ ӨiAcWV~xk>n?Jn#i+M-(1! @4L.Z,//7Rm­J=GJ%SOC:D1*RQᏩݪ}/תMu>[Wo,e}SӿoK7K]lNn\fU`eu{!޺r8[ݮ5<ce3վePC@Tk|58HŦǧ8=Kd Q&`qZήuUJb~Ѷ46XJv|׿?_҂*{kzscڬZlo1은4/`Ll pjYvTve.~w珥 /?G.\KJaOju>[b7|z'NMqޞߗW?RtȤ鞞ii^:wSxLVwN ڛWr[FQⲙ:40X/|{].yftbW***i"SoᏵkU_vj oR䄉lSW_IWgJk3D^j1V4]ye =t ĢONs4淗tݬժ7סΑ{96 n)% [p#_[{Leӻц߾eR/hjӪ_|fi3t{ZXɯ!wOsO]*(u)ԩ=FytËpj޾)-a.Y\G.SV3PQUz,FE ]p-+Hi_د[5q0x$\m.{>Iߦ'4+'@}FjJ^}/F~W9TM١Z:[[w꓁FZHdddRXXXD]III9P3m_o?F``?F``?F``?F``?F``?F``?F``?F``?F``?F``?F``?F``?F``?F``?F``?F``?F``?F``?V)vzfW}_֮oOzpj N[H^ӧS =ƾ~5N^e~Բ~В/?W#[{d;׋wvue')>.^GR v+ו8Nɿkը:ZͻU,/W۱ou.DGt^W̟w;_bI^fG[is?0|JگoQ-{תhDjkZD-l95{^{c+I^1ɼ*v75oR ׯ%nk9HG_ /\gqΣjlX^ys:T|/Q%J{ּGYSO4Uk?1(?o^gq9M2o WRVd͸g|%ohg^YJ=]ꜾLo<I> MRo׆L27'ESkq7Ofc}WHj,MeiѼWѦu[߽yI .zn|]٪G+W?7kCOsd󧂟 b҅gA}_Mš+ʶBԶe6}_J*B}h魥Gly[Y5-:yzZ~U=noq|?* 3ѝ?&vUW VcG|9{NnJ ֺZ k@p>{]}쒴Nt͟; NT[s$Ņ_ԻT|-+ĩڹkLT?ˋ%k:_zuDGQ_}pB-Mf<ۼ[ rd&+4VıC4ճMz JSovPVC={\.Rzu-wNY^W֔EڼlR]%M}jb?vFYܡGу*̔R\Nn'FFF&Eu1 k{ܟ*ٵtҴ7^9럿mј"o?hRRR%$$48v=_p _ai[KL߯d>JZhhPΓnE~[K:SGVhV~`Zc_!])vzfWCRgcm'^H_>jci.w?p8wsiv-^gn.S5:sj~m5\7XI?^4%zOmdvѝs;OtW[\ 5^(KnN*^gKR5_s5:huKۻ_q5 jyl\I|jrNԤ|z^*hb+6gAieWiiu9^APPf^YEzf>W빱ZWcPcH\g.9I>V@mS9J1Z%*Sʊ]5JݫuP]YIYpDRQ%Gy^lfǨ#ZtWm4'.^?Eeܬ?NWV(?bVne}_VkO*>+\箃45;yQw^BI^CgNW1kf[f}L^bҾUKAWhTjP_?ӎJk_3BQ5[J k*{GY.lħ״Z4ouݪY{otsq9AiiǨ9}xMU҇O=uck5BרgԷJ|9&MeiѼWѦu/|m¼ʺb҅gZ%]$yߨӇT\5-%Iw{:xkp]߯iq|7^*S5wrL PScĘ Ƽy UL 2ג͟9ѳDџߏznǓdwK~\*y哛` ~){y^':Ϻt1oUT5t*^SCEjhEpNVSZ)IDATy]5Rjq)'ᰲJ*:<{I2)R:m7Fvm%H{ϗK\u9xB=Fw@>`H Wשw/O-g[lY2w4煓ǬWI!پZWk$ɡ?_QA?+RmPЎŦ-Pr#ź\$אtͭco>PK%#6oaeK\j];wnʳtMUuj3c>C''fEGԀ^ZvV+77 WUFI >RWՇstI\tXG]")m߇j?%Y+ZgxN9{*^s1+uԘՀ>]RCƼV ~Yw<jŒK=6[ԇC1 <\(o픇q7_H?.&9sw)R`ՆyO-RW=ݢwNR\Uה>ںo5px gO]֝ [չTW[%=qܿU>'bրz'NMqޞߗW?RtfuwuR]2 n}Sz"mTtKSQ_Ĵ\@xnդD^6)ZnU_JlAҫh]hQ^Wzs@6OX>"5&VEZxHy'cy2u R*٫z9=j'sg+[A_LUuk "VF$s}7VhN͒R^MGhjb^T_{>ḵj:*U2_XevLV,UoY-*yɭy%IFJ[ [*V)71IU|SޝTѺt߇-ZբelG]5\kn~Vz|}S?3dVp|jĥksʟ5{)]JU|^uL%Mܮ5ʒKJjK|uqLMz RE:x8YSIޫ%Tv. 6H.Uwj^zw$oJ֜K ?)whR|mFrTݵ^\Uu\U!KG|_Fȹo15ՀkF*(;]z+~Ynׁ |*[ oGcV舻1r]JbݍKuڛ4۔er۩y>a׬}ۚ̕F*{um|fP݆?#o}=GN|('@}FjJ^}/}.*hѕ\2uьGWJ]obv`yy_&(}uKTlv\]}ɮsBڝ7@=GkC$%hx]wIvl}|.WI+ Y;&zQg)gs7pnϯ.;RݨΑ藵yUצzKmJz8SEhcjοꎇ);!N.yV~uZtWƩ+_scչeT+%o9l_(u4N7c7OKnݿ׸T'q/jn/="u&jܩyݾn>ѿFg+?Uj?7w}u7v5R5~}WP=Qԧ_T ó%=իK+UtޱI[4tqFÇ?$rb7hK|~ mM݇ kڞUE^~q̕wHW]AռGȾ}~\RJe(/7OEe̲y+0GfL+9OUR2U^~ lY\i5%UA]&Q?lQ5r@Ԗ? %@KkTMcO$QլEʲ^}uSd)ڿyb$s\Gi& su zv:ݜSN#GSY [;*vZw\Z+m.Qz M&wVϵ&&L(%,_s2mӺʗd ~}eMlz79'}TQn4,W=|@.F s[]Wv )y׏z %*s4-q#IޭۨG|G^VJCNۿ*D=ж)15'B[˧8IQYwT;_j//])eJ,m W_%Y"iʐ&:C* .bnOmTJC+{+`6^;2uH;UJ}Vޠ?%*#Y9vEGpKE7V3WGYRu9C{7o۱hЕ^-WLS^ަ48!t~sN#IN,[蕅z=py<qo~ssԿƧZ-wӥ/Q.8Kɇiح֟<2Q޴̇{Dy(E G[(*C$.͚IRߴ11P *C'D=I=OoWY*MWKQҫDm.=gqL&|}e.T~q骬%9/GSED8䌷wԍC**l1O4%*d2{UdlE J9c_\Z4o*-Rl|"m}n3b6.FeKճG 0ic ~:G*[),$gzgwTT"iqP~]h4OYAj5@TvIZuPEE%r:3ۥڞ{vRWFZ=ԿGWrNU9RQQ\6?zIG $ɤSM}lJo.X-w1uj./u6K\ 9=wTyRna^%*-.Oea߯[!$o'Zu9tJFK-*qY6אfMѽuvhZZ^4"ı,Rmt9L:e4x5索=*WVࡃ:u: ꥢ6*4ȡĝq*lCW4-QrZ URrsE**"jRIA2}UmYϪ;qJG]R9;($.>@s%~w>ٷ=wҕ[%~>Z e)8L&W}*lU)6twGU IDATxwtUl˦WBI & E" MQk"PAQA4UJGi Bz$;?BBʶE9Nvg}n;;w!B!B!B!B!B!B!B!B!B!B!B!B!B!B!I(WG=OOG<==tErw`B!B!um6crrr,=Q4; |׷W^77S!B!BGTUl6rrrb333ҾKII仚Fy&=aaa }}}4WZ\!B!EQP^^WdddZW3 |+ &999lFUի^!B!UUX,)Vժ(JxNN&Wwiã^pp𤠠&骞"B!Bqf3>>>&ibIrƕ˓ !B!B\WwiӳV"!B!zQUFSnWwiCTUUPЄB!B!*FQV[͕e]Pjʭ-B!B!TUUEqeYݵF!B!0:+ 1.LȐ\cCxkVndmlXO_O}X1_/>ܱۡw[ʪ=Y.˶Wس-oލy9 Y^BE0bx^.RͿLU9˷o>˞]ذ|!35ǣɈطo/O֩_|Kk'}Б[w:hCغkO)a2k]<33[Ư#6ȎcY_9: `'=l}oXNৃ2W/,y.W^Ɨ#jt'+>h7÷Oͤi'>DB `֔u3 5?1H5U,隣5rB"4Qҧif3jGF;Vm[YFB-|p^mʪ/ӳ ?mڥExԸ/dƭih@˵ug= kf }x;|K_-,c4 6!=ldWZMxq-兦z4Uaή,y:^|c<ދ1-c0W+b'ҬH a" vJʹ8k.G[ 5o7fѴiUI{}c/i?]-X9-GPԯ %v!?saY{8ʷd9l6+wk,؝ʗˤу b֍KtN~;Uwg{n7,}%&%r;vJINuPdÆy[l9g{͕ᬍk"n;5.)d_Q+>3\5?#z] >d`z|V'xrBߩg[D~BL#q6'< 2!cDh-9rqC!kA!$8?,d7H܁''ᮢW{b}lԟ7fC7a6=HVv֥u繳Umt{Qxj@Q0z+=-Oљ/1~A Vrbg-V=;xf2'^L.Y3n}"kvV6?IlX?>KQRrmMї-洭Ϋ&_څ-cI+ߗf~> r䣗0v;s(2x@Nۘ& bmG?}kh81k,c:S4IE*>`Jn3zsR>_H.;e6f5<8oo{4ԙE9 {vGttӛu21]N4 v+*m@UCH`.]f_hRb|[vBQqqfɅH5Eo{G}S2!XRZ7{I+yᮕ̠~*tc q' "+kDc5}o$- ~Z @>٨ʡ5}u5;^-ZRI\@UGf$2VKܙ3NHB- tIMg7XRH^e>tWG%%|{~Ǝx>wkV*;mUTj N%OY}o??4>{ް`sj2aRhDć(_fU[ܙ vJQiu ]MjbM<ÙtZmz5ԩ:av3 +wvhmPN;g'_U0\,ZD_1ؤ5#B!QWV:? >,qcvBQq)-٪/䏜'9 Qz#բq<@noB[6ł'yU_q|0~;&3W}..C%=1hR\fYp I[Ǣ_JVZ[i%""O%߻,"v+kҒ@UKJN~8kK-P8j?IOKǂ#UU{wu3kTk#/׷HZRd…-@Hs/ltݸc}Vdg%Bc4f^~cԄf8^U#TؔYjV4xw3< ݶWWpk\rB*Lw9e NfwqtJX7a!W7Z4{_z嬋Da0ɲM1^ۏS}by%0oPBkQ۲&L5lK#oˀ6-*: ƚ…h|:FrbYNQAz~U'JAջYdـwn/~vC[ҿ')V-}_Xnbwz:>緎3me^8T ᧜ 06,=ʓoA66ۻ]i8dֺ6Zݶ#sx{ޱ+t97aStՂVK˃թ3QVy; _h53S3~SϾvlq/EcL|Ɉ}'iE{&B#xd &F||vu*B?extjJkʼ &>2[; Ӽ,[rB2TRwMd x5]MF>G,*)gцx#wp.@ϼi6b.Us/$*5s\- ٵtKw]qJ[ah t &fT{ɪ߻NM^;>aC7-n8NK([v$#w^iMhK=VoDφx9nr YLMZcBAcxndw #*~Ai3lh֗6US1 Sewr0-6=x|)?ο|./ &ФfASh8cкvSmSGm>Ɂå&X !no֖1aﻯ|Iv<""".5g!B\3_/>u~^o.gW=;t86_NJ_}?w(y#1w`ܒO3RW#} Ȥ_&7g FGGWq"B7%ɘ\HgT6T`Zʮ%˗(u}YZ+B>_b2?۬\S5E&=B:<^>d?o ɶ΢fܷW`Tyg9+W\G![}}hG|-<)ӭok)MnoB!B!5cP Lg[cC8s_K+!B!S!&_ n~+-B!B!)ɤB!B!nJ2!B!BLz!B!$B!B!)ɤB!B!nJ2!B!BssseB!B!nG@@C!B!%.-'!B!$B!B!)ɤB!B!nJ2!B!BLz!B!$B!B!)ɤB!B!nJ2!B!BLz!B!$B!B!)wB!B OѣGV(-L+p tJ,1hQzAjmҀo7i^=0ҨxOhҁ8I܇̜TIx)jsFBԅ/̳|F|dO5 bdo:Nx͗A^\&jxVx j6)fw2kgSZ<^ *VhX7q60`Q|1s`KTWFuQB|g8a*ܿJc ˍTN!e^~e"""hڴiSՂm۶ x饗V͚5+ /``ٲe B!Y7Τ*QZ>RȺVj%=;sR?˶{(XrR$Ä%A1+nή\q&R-4ه MڍN5b6T"Wͩ%Xz,:r7Um$1Ft*!kU_t;+Hpw(Ә&?$FHKK<`Y|=1 ZӵLkKhy֐V]6SݕuƦq-c)Ŀӧ۷/VhР/vcTVHϞ=+NˋE#)2!Ozّ=hU?\~MPQ"3p"ƈ28u>Epͪ{H;3?ťCt|3?r4cD u)ش]Ag!̜CY:ybCU' /s6|gʧ]0~=*goQ39R;OzVg^9ƒIOu%㟟*OTMakJA jm'͓3,^ƌO~ ܝO`yIx &+G ;_dF{I>:hg?աv7m;R}eYiv&0wk`d}VUܕ->euPm%Zv*a;yڍ-X6x^d,c{|dwWlS\@@@UWKꦈ(x`nEyxxcǗ"nU@IǏs?bH':]G'?ESާx>O6~6]wqƏ-ŏ@$+L5D~sٻ3>3qٙ<7Y?\"J0Qղ<-NSܑ3>f\+=\zOn@^O1L6~iф鴾 ?iƊo4&AZ>ߟ!(Fu ',ݲ.ػ8L_?aLgXUrٚRqy5 Q@Pz4I 8UWQ=LJp}ĤQ)qQDo^4[ \G4f0ɇ+wiKUw^Z2a<&FW(:Túy3:Jݞehy6oi0x͆؉$W\ Qt ք]| ޞN^fB86o6. gwTvǩghŰqб^K۩;ֱ/͛S&Mx@4y$:i,KZ͔nSl[ihglreexP *3폓?jqa\ ! @``"#Gj'=TUZjxxWz-e¿vni@n3ĺ/~ t4-Zԋ"{9Rr䦜𑓘%tٜ\?7C= {<İ0ϫwI۠S,} ǩ( /( ?V>'XNãg ؉擕K.g~vg\qf8/&|]f2 +-ΰOTuhƒ}:O]~~;;sŚ+uN݅viRsU*FkòuK-Bģ`yaV3Z ~pK\Q|'~ȹMj#<ԣ3=si8{ ^1[`Dj-?UbdY4gK°2cI'm<`UʣeӺAl?.,bVw"W;xqtGmgΧLBVZQU5pE>}+(DEE|a!np* ODk4@DFW3(/8)ZW#Rn|P :V `!GYjѲᕃe&!0$f4 6 :~clX8֗ k¥m ᕃ3% -'ߴ̮(}M=?^dW@vLyEvV.`#+'O .ţ5gS)x(9RATHf}<3\IJޛ5Oc E<EUA,z_GPl<"JIc1U|)_R,:_,8tE_eO,>0˿>r2mWMTlNX<*[l#5}6 Gs/@!ѯ~V4LR+ak-2OZ\:ҡ?ʳX˞{|WK41/Q9,y-*q}gsᑧʹipG A'W;^:mI-MR^aI&c{j/R\3ygN(SF a^ZFŧI^4ǞtcgIT3SZK$Is:ӬtТZ6b;ۯrJKTJřFR)>4bb(*CG$鞾XŚ*Ct'R)0`3HɍͲZ., Xu!j<:\oWX\ߺR?FfVaYZjw;I f l FRj9'TUQ#&=3 %.eAg&pOyNr՟ ^Lx3~3uOL{ne.'+K`=u]iTL x=Yc;3)nbA4'[@3F!5U'}zebmWzEs99v#;N AğlݖQj=-hނnॐߛ?fhY&uRe|y?84T:m܏xz7QyvPڄPhks㰍lUIc9?\mq*.?Yk1W5+ĭӴi-iyyyɛ2DNCTDΟ?3<ĭoe<~(\mҧO7E(FGGWqܺ+2&]i]-? !vV=77W^**LQe(RRR/( oo/jĿR^ZvmIhA>wU !pH4 VN;w_~ Q[Nd2 .z87E'!vZ};H.B~gN:3ꊢp)MFHH#Fx?‰'2e ^^^nP\22J??LB!}Y&MĤIvAtt4l۶CbXh޼9ƍsK3g7IvHMM?,zumEh$11M q}ȤB!.xIHH ,, Wٳg_ׯ]tAѰo>Cxx8zwүo-[K^^ݺuCQt:>,֭uʣPJعs'㮻⥗^rKBn?ʌy_^1#Њ.gFlNo;s!?.oOѝ|4XX:bU܍UR"ɪexSsZ9s& F|[tNz9{ 3qE ]C:i^6y|8ysP6kW%@[ݠDqt= >}&׺fjkV= _ԧ{;vлwojԨiAnX,( 7.:`UUFCZ۷/111L0-yɶnݺYfRCUU6mnJO@@mڴA-i OasYίkw79~B ףiRع0f]XRiAch8kփ($[tݿkqק^{?=z^ͥr%>L^^Z.]9`-C]I&1qD-n|<͚5#""dF Y&'NpۤԬYӧOSzuWνދbg[Ŀ'=^f%͎Mc-dj\u|iU?\~MPQ"3.S7;Շ3^\]t2RꨎYSR>n 2]PǢߗYrzsLGP.;| 6T6yZmվ6zDs>XMgc9+fK1s$/]OW]A:bo:R SlW`1íc|(q+ }8#Ⱦ~#ޅ+*DUbwxGKtŷ̟1 x^HBbT/z~-낥bA7q~˗*Nb#P9Ɋ9lM"`D\.z` m\0ЙqG q-NOgs |iKW d*u{8!+c'>J˱O|Piٳv%[H=WMb\u]t$˦.L c_aIuG'?ESާxbr[%2mփӲ+XRۗ+`݃TnC+\}XY]]J{4IcԷYq.+vcMye& t0lS՝ }~YmO 8ͭc|'XNãg ؉oǢ1i x8]v]8ߟêD`mQ 0[cby*iH߳`1,$}'ծ'uJK3,z5Ӏ3iZ`Qҵ&`?9nӑg3u.v^Y`#veWI>GJܔs>r3~]Wq3&OER) G'M]=Tza9K_o]: yja\'Bm[ߩ6~eL=⼯ܾ w\WU+(opV_nC%Ӻ"}JY]3nx]3^cool+֘(vc%fԜcwwY{ig57e lnO lgJ_¶?fsLOkBoԨQdeeѾ}{Wq>}m(W+''4zt5 {fӇzGy-ﭷ4mڔ*U4k OOOASQFLZXd  rK~B'=G7'^:Ւ-MƋ2>mbʴ5.4 ?R80&VsfW~>& X/dor}T @["<̖;+g<-*Fs,|ӠEGx` b C7RZE6/C-=A[1X^ cWwZv[u%-\p/tUWJG ;k)O**0Gkrwq;Orĥqa7Rڶ mADÚpi_Bui|( <ۍsaT]L;r]].d}bs8~ 6c=F@@5;hHJJrz]Q*dffҥKcUUVZѤI֯_πh۶-cǎu9 qc8q"{%++>}\+}}}W111h.wlAUU9h #??LL0tP,Y̘1cךdju;һG`8MjqY>m?GgZc\xĔ >TV x%9XK5Tt 6~LdŇYm5~l㕴A(6eHJb>Ųْc4S|QS.a2،BbJ]){IƊ.(2ZjZj}Q(=젎W3f.C9^꠽Wqҟ^Kuar͵뮵o1y{e+_yU4x5)[ߺTwe*`?hLw'Wtd D˓O>IHH7zLT^/Z.77dӱX, x"ƒ[nXX>>>FTB\\K.aaa.EnHII!::~ѿ zٸq#fAa0\P̥K[ IDATjhҤ fժU䐓C||<999xxxL@@AAADDDx{{O(B||ECjte@SmLYK@vDjoE֊#Gu cQ9o=^|8NyYShu$$))^6vbPIزn~w`ò$R2?)͛*'1umYHhlauwu'm㠎ßpUJ%A,뫎üRgk%?{U=LB {QWĵbcZ]bYTEzhҤ@H!:)3G! 3IG? 3=s_w4z_VzǐZ2ka[lW^^Ƈ =ﳏ^]mo } 92*C%xI іǔqPRz_,'zk͇-t E!,zO²[] ;KHHH RZ-{رc( \]])))wwwSH E5^g\r|JKK&:vHhh(7ofʔ)=w3*}!WbgޒPGNzb8g "J>r@49Cf>~ߞ3Fkp]\ !LuI*k?dd]- o81#uOL~ƾ#a:wpjlњasS2_e{ +gtDLKvjlZ`/S}gn5* Y7o*hvN"'@JxHHF=܃uMAƚNĐdx{{3c Z- T*NNN%Ç7oih4ƍGee%˗/gԩ=Zp _sNΜ9-ɓnݚ^zA۶m0ˋݯR\`ĉqU~g:wLTTNNNם^$˙4i6mW_?nt$$4~~~i^^^>--H_ՏڜҤ7qM7,{%ݯ>WRiS ŦMXd UVBzz:Ofxzzj2%"i]>#tիW8p`ےdp)\\\0`,]_///ڷoVm_A@?RRSSׯ_ǤqHaa!iiiTVVg۷/֪RUUő#GPT|ͪDM233ӓ"+=n/toц \8'_LSJHHHHn{v8E)!!q#/6l@uRAӱg aL:LVk2RAח{ j*رc [ |}}MG[q5iDXt)111 8ДhHWU˅ 8p ...D~]wkAر#:u'OgO@@ T*ի111|GͮDCVzJdPK<ƆoLQ6J Y>9[yDBB۶mёݻ/65y饗z*(2bĈg AnJaa!sTuL[vv6-gso^eee]Smj2,Yruu+oزe FBVs9;FPPۻ54l%:3J%h4֯_O6mСC-ZD=hժUTPP˗9s ]v%003f4컙/s郷7M^$X~=ӧOGRz 6裏""JB!6R.^ CjՊ'N-%>$i{_,YM61dӉcǎL:f]QQQAQQQRRBRR[APh4r9:R\\\sɔd$IsB.]С;v#GApppΎq5[w7nN8Arr2 x{{ӽ{wʎJ2rh4_`0*0*"NNNjTTѠRppp{{)ޞ(ˆe˖-mۖHd23f`MnGBH+=$$$$$$$$$h.]ʚ5k$77f̘Rl҄xE^^111;woootйsgjMZ͝#hj|r nseŅ"ӑdc=֬Or!Yx1qqq'PPP@RRtԉ.]V[lL&_.6A@ӡVk%<|2eeeIQQ.]ޞΝ;ӵkW1 N ѣGٷoܹs` kܒ[nPD>ƧLoi&{!y;aZ϶бjﭵ\nIv6rp#nm]k~MCD˰h"^u"##6l{6oj,d2&99L233)--EPAhh(׺Vu͚5xxx)**"''l^Jaai+J2`h4&Wt6LR4]#M״W]+],mA2멪Jj \n:& JEEEI7㖣 DQOOO<<<9u}R #<vvv׽gum[,Ҹ|2999TVVhj兯/ZR`ئ=@FFk׮e߾}L2/i$&^0&U"Sc~ƒ3\W㿾ocZ'-ܟ)=F7&> !&<`6f\Z^<6՗Wr|yG뼴"͔gl!̞=u1{l"""ptt8k"\^J޽i߾=jヽՉ_sMu{%̭@3V@*JKK Qqss}#˯k%O1{II 999Uh4VqppZ `ZP-0b[t/9!utʹ*77lr9M6Gիzooo<==Ͷ'[_dر_Kaa!{1mUgA&cp#['w رMӣ]vkΔYr%ZaÆzݸEyϔ)SXf Eˤ '_oNս/v~u=, ]b/2C `/xy ,ʟ>ɚǸ* e.˗?'j<3ڽӉ,ϒ9_ga2(vj!s_ye'k\Qj}:6V3ny6-W[$ӣ9+>_zCyH`oFYVbָq'yq>`[/Їc,ElR6 Tg+8^/ydg/4]+lɓ'?… 9zKkzM>}9sf&!B[8klǐ-dfAĔatw6sMޓMͦ-kS17C RJBNQBXK}- WƟ[v‚Q !Cj'>]ȯANn4Nf[+7P3lO}AkYGOeClUKYCj{"<応EI<fjHv%pذ-nsn{>ykm5.GG }h_-6:2/iw3:+4\*#Zb~ĩvY_w3ct\[`_oy|&Zy?5|l~ɡ.n[ܟQ00q] )hz={`WG0;Rv'܂y;WyhXoSa|/s諻Ô`|VZYK Hgv5v$$lV\ɓqvv'zΟ?ϱcǨ $$I&ޤu OQQŦZP|Q舫+ZJRD&@FF,;pppUVz8-&QZZN3WQ(sppWWWr9 Lf=h&Qqpp $$P9s #004ÇYv-KB- /Bv]Uiow<xtiG(|ȣ?OW4*T@$o1=.xbbkxmWPQ%"#y%TP .-!>S [qm XAZOꨬvMذ%nSO^@oOTZ[F[^9$!DJV()n&T/VYuWZno Tb>IiՍ, 0ƿvv=yӅFP*|˲+|2'JwNfj` [mRzD$}vN>ܙУ[9X`[۶ҽ6?Scv۔spqqǧl֮]hZML&ZO9|0(JE$puu<==qpp@.SUUEii);wDQ$$$R7n~~~M0a1Ls:u :tBII (Ju(JzPQQYYY jM'ҽ{wڵkw][1^兗Cܹs|j:vHϞ=$ĉ_^FZ(EL 1/+/B_ڙ/$r+c*8> __g얟go }՗xiI^cГWѓ6ՏeȚ,yd579[`=6l}Ͷz J OWLK#~ 4Ez5倧}niۗ6_ol{c|.A'hX7dCUҫ<QTYwz4W,Ԧ%pt gمx-I1rr)'=M!Km'-W]j}v te4ߟ$$,,Xu駟'""{wwZ[]lUUUN#!!LJQ*( hZڴiCNjV^^N~~>ǎcńբ[$nBCCx"$&&2h &M)+Et:EEEdggw^Ұ'""WWWi۶-nnnzǓ` 44PJJJ8s ~!;w&88R$!Z(!'dسL=@@"pzRt8'4;wrb³|rW%Q֖ AeA!(E#P$et+DbJ*D\ z,n:vDvӔl:Ce:inBl?(¬,gd7Y[5bCZ{!mmE2T֝%PqZIB]LKgd3).`:dcwEzdKsu٬A.'TFe"p(SD )!!t;!t\_-aFĂ[C){K3PMăQdl^9ksl'͠"!{u?\T6IKmٗ5dWWf iWBfʕѾ}{ FiTm RSS)(( !!XBBBΎ}Gڊ h4iݺ5={4C8<~~~I+>BA@ӑ>|8Ǐo-Or\F???:w` //Wb0HNNfҭ[7Ĝ={$**K.( 6?5i-:efG]J.-ݻ~ߞ3Fkp]\IF=7{_ C;< IDAT+3oI*NZы #'f=1%9 9;v?t)lX30!Z9~LyĚl8[USEEZ6_}Տ_>u;Hؕ†VlRǧ}S7c-M+fl?0r.swr[.׷S}oXiHsɌG"$sbݐf:Nd+d%RVeMs5!`@#!$G"];o!v@PjǠQ5h%uXe ,+?(|c[JzHH+®]իAAAHA@.s֯_3%%%ѿSqӺggg ٰaǏ'88^zݒǪJ ?L.]5k齖J @XXҥKݻ `ĉ&_VNxx<ϟs=";;_MzG8=f㼲6֕yb-6Z$n"6'7OwBBBBB↱|r6oLqq1=\0N2228p/_F2`M{LӫW/BCCm/w0 `0ؽ{7YYYƸ4&HΝ;Ç#**(jMcH8~8? Nfffzrrr>B+=toц \8'_L-&Sɶwk׮eȑlڴ {{{v LFff&޽7774hP*pk$;uQ* <Ν;s!޽;mڴh: ELL :ubTV-1' H:vHZZ999|1777BCCQ(TE'88~w}FvGFJzX`d*ln)Qd[ ^z ZVET^$`0͛E___Ss$1?n(ȑ#IIIa۶mЧOJꎸ8N81c=*VW}x{{Cxx8.]ܹk:x T2:wO?Ě5k2eBoohi;~>z=6m駟~39ydo-rvM\\'00f$ ٸq#=ڔLݻINNFuɡGdeeq -[vHHHHHHHHHܱ?~^zj]Otݻ///"##iݺ5UͅL&umIIJL:LRDѠV3;C 0bbbwxxxQɝ;A((( 664ƍGiL6RPP@aa!eeeTVV( *++)))`0jĨj4 PQQ^G.VqqqGGGz50`z޴_=zm۶#˩ B!h6l`ɒ%_ӪU+<<< WWF'Z1S^rrr(,,$==ltrd2rRJBT)//^oT*qrr ///;;;SR!_x;wB׮]Q*Җ[J9uC :,..իdggBvv6:J+vvvhZSBĸ)N @qq1]'ZZmJX1QJbb"gϞ%''h(\| ϟD+KܩغOzH'H(" 7x4?8|~oqpPMi [SN1eA`ժU >P>ɇLHKK#>>Q """VJBP>f ^Ņ]mzvw}Gtt4]tM661tPzƍQ۴E撞qsscʔ)8995hEOBB'NӄѳgOPTgCeRSvXXڵ0je˖-\t ڷoOhh(Z2]_+<˖-֭ٙ[ӳgO[o";Fs+O<\&q_onjH8n"-ZESڻcFBVeΜ9$%%Rغu+]t!$$A2A4233AEppp`̘1X|:2A@VӺukڴiN#%%www D۶mC=D||<֭o߾jH8A '''OÐ!C7_? l߾PyT*uhlO.coo=m۶_~QPP… qwwW^]ExV\ɤI￿h7 FTxws!w Ew$axgs&`,ϜHΰ}\FT3쩧ү^U䥝gceUŒt Y#,liV?덦4KE_bO*p'+|%0k3h_9s+OEr)ANii)b(Jz!\]]ME777ƌ͛y衇jZo7;1-s} ۖ)ޜ9NPwq~=, ]b/2Cgy^W\)K>ƅTk/2j?X ,Exf>9 *gsn_!_cVcW 9'зʻ,;orpK=M,;ˉ|x6[]PEp]sdZ gFn^ulZQG]7<-}Y/=hӤ/77~O>ohƌ}GNKxxzz2yd"##7o)c A1bO>$gΜaժUdff >oΊ+fڴi JxdVZŽ˄ j%ܴZ!?k>9m׸|g, աb_fCo#dlՋHذA[Rg!Cj'>]ȯANƇb0%,e6x(]dkV"}sBn-Si5e(hXؘ!p*8~ aDGJHY,G#:ّs?i[6>\lVDZ?gc8o̱cҥ ;v`ԨQ?gp?~lwNhhiJK:/&M">>3~xM)J~RSSٵkNNNӶm[fuLM$:ĨQ9r$vvv6ʨĉl߾3h d2- <==2e c@|bɨU4AYv5(-Tn͘lϠ*~R3Ow}>ڝYxO,xgޞkɭJ/`3e]g=>󵅱s:(rcfcG-"r;5@oOTZoK(?zӅFP*|˲+|2'JwNɴW{s>wߚtVk s~uqdSbFBBgΜˋ;Ӹ EZ:WI_;<^偈]s_v^GOں &xjff*h˰zڪ9]U(HC}rnjVLfٳr1Ua l>V#ʪBeEvMf1mLred_kx.in_xݬz-^Əh{=%e`熧mi#?8x^Q3Cƒ\Ж9̓z(|\&Ǥ>jnlܹs9u;lʕ+^WWW&O|47'Nd|̘1'ή](((gϞV~n&)))H޽i׮iLCG;wfU'Qj7Ǐӧ9{lB$$,BI9!Þerr<rw"9;91YF (kKd`Woj<V鳉dŔT 8t3_['`gA!(E#bqrMeT)*2%J$nI.BLǵ[?p@C^G%Pu_;ӓؗhcaLPw%"YMa+%"l3w1&/7'.Cf?xwLy$ 0Sb'y.N^ED?bdbHdr qkMҽsK{infﭶٺ1hkAČlܸwynݺi @nn.=L0nu֌;={#P*6]+ۗhr ˖-ŅMGT*J%JҴsEnԭѩz )))1Fjj*3h!}E?ңGBBB5Tۥ]vexӧ֭7[=F_M1&fe`>nhp˞Bq^YsC݇s 3-ZDppiba8qUƄ 8z(-b„ 7)Qs[Z`mK-g,Qw KChjRB سg?V{$;8{,"$$<<HDDEEEܹSlٲkOΤٷHHHHHHHHHH4fѴk׎*V\\.o߾Rr9N8Ktt4pk01ٳg駟С;wZUcѣ>|mJ$ ֞I-~_ѣG~zqxkO-RCBBBBBBBBdɒ%Z^xB.]Jhh(-:2NA f2 LVk@ڵRyFD~gT*cƌlj*2d6JAAN"33EEi߾= ^Ͼ}0 =T̶|w 6TVZբIHI ۚ^x֭[i߾}$<A`0JNN大Jqq)Q`@&A6mpssCEVCKŎ;G&}%1Ν;Ç)..W^xxxljQYYO?7;wF&D||̜9 УGub^UUEvv6ǎ#11ZM6m  ! $Xx"HQQdddDVV Ю];:v숛 ´5VAϙ3gԩ} LvKy+cL ***8{,GEv튯M}%qp=lgWZP׮>Zowj!Ԓl_:n!gϞ=1m4bbbttD N.Z͍7@}}=YYY]J|||Yl6O~̙3|ׄ !.or-(^rF#dff:L0wwwry>$عs'C A&?0i$bbbZ7f>`ܹ\fLƤIx31c^ۆ\?EիMDQD0d Sx{{_^$~.N@m>+:$<͜kl/1{c<;Pa lcQc_cz';ge "}9W`mSܧPeSEPfW0LJ ݰfyhobx0- ᵇ}j!o,O4_3 KAw"w"ċ?V|=5>[s-{ V}}U&iMekI;7ʧsOZ6!koK-ODcc⤾[?«M鴭qẎuL ^N] zcIcF;D]z]sz_{|w3c)}V׌=G5->IL*s zOvNBBBBB#- 7|Cjj*sO8/'("̜9sαrJl´i֭[Y0;t tw5~2ŽcȢ?塑i"yMvL\:{xkSƑ~o}r` 1=P rcC@؅猪d8|M'7icǾՉ6,DўZh`oJ蘴d V7Scvub旟Qڛq* K'#zy'懼YXs I٬b-`J`5ֹ){6I?0Hҷ-hG%$$$$$ &vmEo:^z%<<<:P!"<#TVV'pwL!d2=zG hlwES=._àBWhG0%% !qƱ{NY{O?ݩJ\]\o󧞳e ?Y) ۽̌*"dX7'R𑧐>ŊU}§3<|~ 96/ߠ aQ)&cČ{<xhTPpvյXIna ߥz7͡ $E}5-A!@vo=Fa/fb/r˗H2?"6>&*\j|3V9^=I 9Sq _Gg!wѾӅ/CP¹E:JSd+ hXm] xbv< +VW^L0θQgرc,X &гg+Z KX,hZrss;Ĭٌ?dBLL [l6%>d--hй;}j}=m˖Ɇs%䞑}QdKSz{u~w}Pv!Uup!лBSN=d,}?>p/\uzQu@_v}EVJUk]ٯk琯#WBђ]D<$_2zGK-IcnHǪQY>^Gh;H#rbnl=H/&_r]MԘ?UQ͚W̸q4\Flog?*]K{ ݜ/CY ΡC6lX7XsmRb\ET* ⩧⧟~b֭@;%$$ڊZ :D l6***TEY.SCNϱO0apS1@M7}c#oϜ]Ǥr؆~vnOPKYDm]/Rsg=?G12%/10Jck[[`t.y\<6t-.["ӟ;s(.IiڞfdE3rD]J Z7-Z]M]yѷo6]+"K,c̘1W]Á\.箻"))ŋSWWwUHJJ";;`fsHFFDsgӣG HW.""" B\qd[~&9x;hW13f ::[Aѣ:uG}Þ`_IA`ݺu9riӦhJxOD.~O5A믿FT2rH-h4sw_#Y+WOzi_PRRR.S"ӶHnUYO xHHHHHHHH())!99 ٲ2l/|M](&il|tD{6ܱc'NDv˱dzΝ;Guu5y<@&hpwwLJ E+رcX,|zdtFJKKIKKc۶m`ZQ*rd2s,v;vUVaeȑ$&&ҽ{w%ח7|[oGcVZZڦ`eGٳgX]?"!!!!!!!!!ZxQ._#̞=c N>Mff&ׯٌlb`6E\ZFTT*tLDDaaaCE>c8p5,6llN;:vtXp]w*_!"YYYܹ'xV]/%%%,_[ώ;6m~Cs*HHHHHHHHH>9{,l5(i&nJe] "fo;w{nr9r(x{{VE&aZ:J%yyy,YRSS6mQQQN[w[oEHH!!!DbrJ֬YRd]QQ` 44Pt:V 09N PSSoA~{ wo@=XlSN׷E[9?s 6mbḹl߆e2rfsj˘ӇիWRCBBBBBBBBV/td2DDDtH%Kd(  #<<gm L&d2QRRB~~>rJVX#xGӧObڴiZ3gWA8y$|z___zBBBׯ wިT*vs/p!J%nnnq2~kXP{ѣ,]XFN䨙cnqFF#ǏGRԎcgNYY_~!77 L&* ___"77Պ;V< `20 8pR ~̘1VEŋJbbb[%ؿ?}2 ZjJOPP:%fr/_NQQjFMM C ͭzwp{v;f\Rt#bPXXȦMw"3}vHJJjuVZšC* vl6(h>}:Æ kU`ۗg}UI\zE zHHHHHHHHH\1-ZIIIiu pBO<6ZAl6tR L&vx/x\Ԇ whyF#Gf̙.+((W=\5ݽum$$$$$$$$$$Z`(J|||ZungymR__;ŋxyy1vXbbb.(l69s YYY䐛K^^gϞՊVmdV%::OOO)**bӦM$$$EFCii)fU7̛7N̅SO=EDDD$HMMSNRj:u Q]qYhTVVRUUEmm-555zXnǎh4ңG6Rj5t֍pBBBjS9>k:Z,T 777f3FшN###JELLK}fǎdggWuuuUUUo9)!!!!!!!!!qŰZ$''zAUYYIaa!Cm~[oŪUdt֍ѣGn\=J~~>DGGETTt ???IOOTTT8_\QϏPʨdΝ׏`nݺ|rx\0LX,J%V^|CRq1 j2xVخ͛7GQVV֨/9777˒vX IDAT8qO>xzzvֿa6ٻw/nnn$j0@R9j<==BPPQQV%--ARۢ(r7m۶I+,^ԪJKK)**bȐ!mj(ÑraL&v(--ɄݻwgϞSVVƉ'ゝ#RTTDUUGib\ӑFq& 8x3F'$00)ٳ';'O$99K Ze͚5jgGi^ljbٜP9x {b 6fZ#@RiiG͍rr9uuu.u777rss_:+])!!!!!!!!!ѥqss#88RPZZJii)IIIvӦM{2zhٳg2Ç@ZZcXGK= BRQUU^,III#G`XwhɓzΜ9ĉ]ڹ!"TTTL&C&a0Χ YUJ%o~mm-w}7 ۗu8+*9{8\6 }vV^̟qssÃh/faZBb69}4 @\]"77?ؙV'U*j*++Zx.]Pm6-kWRZ +bi~Q۔;s pal6cƌ;vϨQ%jdZbbbF222ظq#>>>5Ln RIMMe˖-9re˖qwKNNO?%55j;4l}$22DQl6cٰ픔 '!!FlbY3dȐ6bi */J;=kVgA(++ɓ;S qVio2>s1vbcc;8uuuT*)((`ʕdڕβeXlJM \wQTT@߾} ,, ___:Dhh('N璊MuKII ;w$22~ t֍h233ꫯ?~K ;///AնMQVVƮ]:u*3.zYv-Ʉ6iG(l6뇛[,EQ$..Nju&nvQzz:70.z98Kӽ{6jYz5:Ʉ իUsݝ޽{ng׮]L>Wpi>|0jZplf>/"=z_ڕvh{M( 6zjF慘c!ؚc999Zʹmxf3=g.(hdT*222>|8N)h4YfK} JKK]sv?L^G |G?^^^$&&2k,ҨhThR 0lذNyLxx5Yn {1z#Ohh(O大Kee%GqڼG(VJE QQQF֬Yiv$uᑮ&إ*rv/qm =$$$$$$$$$:Ю' z)))l6#"9ww֭[Z.-HNNfܸq8pX233))) BTe\^ 7J*^^^r-޽ѱB ::NTTsv;ΝkVCR\nCR1sLlf* kSXrHL&EEE&;;YcO+[qohwW?RCBBBBBBBBSY`A`_7zU oyde„ dgg@bbz4 2UkDQLJ;,"""ȠAHLLd2q)=̰6//֭6Idd$ZѪVZ|&(-JcTVV2lذ6DQgϞYWłBhծjV'm69t:]剢``РAX%CP8j`p92dgϞ%..V@TT hNs9Ñ#Glf^RFӹ%lӵ2 T !:AX,΄ mt:MaZ;:Rt\f.F.;wYtdYQFzL~WXazH\t頇L]Jki{ '֬ge.Jҕti׊._k/%-D}D;j\mJ-!ёdee.(2h vΑn닻;QQQŵiq퍷w[UÃol)**B&L&ĉ.(eyۊ#u1??? Ar[z1A@t:Nݻ;myF#G&44׊Hxx8{mW7]'衈ckfXYHNN6%=v]RFZݑ#ə 6nboFWN8%ܹs߿,† ]퐟n'!!L~{dȑFrssEN<}z=nnn`AUKKKX,.=== s&twwg׮]d2웛[UV<<Μ}1C֊>+KXLYSHZƅOuhuk,Es̶P \صCx(啜Kh+a-w/]x샴_護UYmT;L獧a@xmsX4;-bu쥾0uIG٨|I[ؚ&G7S6"0yk&۩6޿Nٚ;Lh72WFצIuyF=Iâg9Z|!h={QW\y˞FS_ıxw>ιx? 2tY СCٹs'ӧOoV(FHHx8TUU9+5:V%&&sa۝I_e̘1M?~`xyy94g g}Ftttȑ#Yf eee>L6׷QHOOԩS~TWW3uT .IׯqH\txx.x-#oa#+x'dOtcG ]abϧ<_YrtpGʉ 4oGx{x޾FrSܧIޛ;Kp$Gnuf1m!M{c ̒w^}y'TŇk) Ǹ_-?||]hzgIaPO2],tDs] OMb??`.(˃Ėy2+ɳ #͎˜E E\}ȃ@m>k i.R?y/зn'yexy^ܟ۪>5/ ~6(#aC5^.gG6ges\gbޗRkl<7{i3/MȻz[X\M1qؼo C:.|>|/^;s){6߃/sNKwſ/Nl~^JHt!y:l+"ɓ>͵N>}LW^@aaj[<`w.QQQ >_~oLjkk1 L&f3e^{5Fc~~~ <_'`0Ȟ={8}Ȋ\.禛njr9'Ooܹsd2 ry뭷W^/LGjkk-_ PUUERRÆ ksv*c%<dڏYD}]Oϭ޻PK1 r`[ XSw}oz\pmm%[t5"7޴1בaޡ\F&}5?[e&'ess DIf&}6iHqguh޾S5ᄂ@l7=&7idRdLu.|sc繖F3lj\x":PΝs7kdǐEC#GkiXBQRR4d2ɬY~`b2RSS;Hx1L&J}ϧ[nTԩS9w[n%##,j #))QFբ* AeʕL>s),,dɒ%jDQ1cߢZI&q9ϟ xyy9+zAA#F`xxxtH@-<<ٳg"ZUU^zq뭷6݌U]e+K0lvW0_X} G¤mvxoٲe YYY.((\[[N#66)SaIAcŊq"Ssz(1^&CD7(.h75c9Xl=1b EO.u DȩcVt~6$E};9rj|9|\8%OIӁNޤœ)K׸d#ֳݻh)oc)> ik9/EmJU8~5:?n'"sc r]}HzΖUC/d-ׄ> 7cۘd.͋obO8F$#O!A}K ڴp)- ijܕ-̵--U(6}աM5}{1$4Y).|+ڙٻ_pn>]|vߎ3OXIna {R!uXjg*WE9pDFF^ݎdnwXώBEBBB󣰰83 {2fKK>dn4S\hFp?XZ6DRqmpB^z% `r5tZpJJJO>~Qnzu]LBQQxxxhewq۷_Rf, sATZn?(/Çٻw/GnL6[WWG]] 4#F4KB@DiĻ`? يRjcѨhJ">6,a}]?&Mrd2uuud243`sEݻ_EE=ܴ2h}؟}եpk\Bx>LҕI//8ugKُQ1Qc=7Sk+{:faz2iF9$=lmȻ{SCN^d"* Ctqr.= ̙3bR=x8r8x|zpDb-uf/͛9tT,Y8}]3 /rW sLs1@McZx%Dʷ1ycԭJ& \rUjOJ/j8clm3Ϥ5ygzDf|0sX~Ґ}Ǝ;Qg<.0f#sa̤>h38sLVwQϻmMT\ȉ~JbÝE}.XBcYz5'Nlٳ'?SLĥ` << SUUE```no GTĥV$BBB~:$HЙt:f͚;Cff&:Q9tz+mNziV^Mzz:nnnΊ*FٳgyU 'ׯd:wr( B8 IDATs; 0@FqE ef *L6d@w`O}g9{?*C˻a2܏%$:8I^E7ȢEؽ{7Ç=LvAA&q)bbb8y$Clz90ܹOOO/ףP(:uj2L&֭cԩW^Et:O=}iiixzzVZ?aƍ9D|}}Q*dK8v rrrشiNf9sx#˙3g111WL&s' GߋQA8}hGQkPc`1f&^r)el"z}9UԚ Ongy1C:>cBG#"J+AAAM%$:K^q%YϮ812ۂ~&9x;.%\[6G'Zw;7>gqQzu۪aɒ%L>XF# p>0Xz>LJJ%Gb.F[%\Xt)̝;]*Af߾}L6]̺uXlh4DQt0777j5~~~t:l6ΝNvv6_[?M%S: :8ʹJ7XPT3;(bbʞ5f*%6_x S@wĎ/ z, sνҪHt%%%Eyyy-a9 NEAm2~ӥ"ao>g[+Zrj0ݪ8d5wmFWGBB9jjj:mɌ3Ox駉BTj9vzp 7t^TrA:Q(M*77G} W#*ɓ'Α#Gt:Z\g.A.x  W^!..S{ԕQXXF锶DQۛGyO>ӧ@LL Ǐ`0\ .A ++}6[QFT*O?4lڴÇS__L&CR94HjbXX,T*7n m r-!Q ?{Wy&zwΙ4ŒlK%"c16`1{{ll6fBB$al+6[n.YO=?9\%jD8hNyΙ33;>q)[G ʱ͸E}C6{fH`VKTZwC]q|=VJ:v&GUحڶmK.'  C"44_R^Nuxꩧx7 --ݻwc`:{,>I&]q믿NJJ 3fՠ>%hooA$L&NDD(d躎je֬Y5Zvtteݎ@ӺcܨJnoQigt.n$rt,%@ѐ4.23MLLtS9[}%ez,IsC`"!  A/}͛7JQQCfV}X`U۩677rJbbby IPU2:::PUcǎ!I'O&77Պ"H,L&.\C8}4G&%%.Ү?\Z#PRZI@[v\.n۸& JPP!!!FK&yܔUAEpIcZ rؑ$_Ln k:ԝeTPpNԠHp {7, 0n{ңߺ>X_>7)IwT  ߔZ!0{`$''_M6|A~RVVFMM ?я? K;=x<n݊DGGOff&s&_?GEEix<8{,G|RRRX,~xFTUi%%%܌p`ٮhW4n7n"##$>>EQ%p{ghNK݇ &lݝZńG-!ǑP+n/υpgcgz-ՔBls)t2ñ]4WO]y29H]Gik(pX)v/?zi">;}<7!TA8x CbË/ȳ>ˡC4iҠ /0b_Ά O#H6>|RY`iii=z%If1j(F,|>6mĎ;hoogل ?n牋CUU"""5kFBQ+\.PTQn7Ŝ8q"qbu:*m^ZPݳ}B6X)`$?$ 䋋\Tls$!jthkKl6(ZiؤZ_|7-,F5˿<3 W!3ft:΂]8dt32 thA^?^hRwC4ePVtd ]YgBVb0Z䒘ȯ~+~E {S7[OaM5͞C7S-wɞǐfBL :5>jv댛( l&7>`+p>iӗ1y]kw}]; 6W&eѵf'"5X&URYc(_w.Ol9j-ĞuƇV[˧  /gΜ`ø$&&_'Or~݁(tttsZC_BXXg?c|+_1f\eSNQXX#.e$.N8ߍu+/^t^7&(:?:#,GοKݏ1C",Z+.#Wq  Eo6`qM$QPP@RRoo~Ì37nrI&o8Q^^u,Yٳ$<;9%nAAPYYIvv`q]??}vz-vMvv6@l6[cfVΡC8z(<,YĘIp/i6l %%sqQlBtt4˗/"U:޽&<mmmv(f#$$Ӊf#443~x;wp8HMM%55b֭[lK_6͸txי3gN*C֭[_P:f<Oe׭*VlINBC)oolm3yV 6H3nƉ5q,_ڂwx>s\?]뚚.QW_KI,‚$k(٫;d2GGvTu+_8̈_Re#f  wzE6~̙L4Y~='Nĉ\.{K`HPP`6;w.3f 44Ыֹ?cf͚Evvػw/7n &&>P̙3ՅC4BBBFQ#&&`L&>6ꨩr*mmmx^N>ٳg㏉塇bرDDDהc=o˲eˈ2*=o&#F|<9rؼ&Fe.\Ȏ;شifͺfS1?k60PN6vln1_ciTLwM0+\C6=%6'Hë{K`/v8x9)):66vMAAK2aR~M[[]]]FjLppp }:;v !!3g"I>w}ͼyz,|ٳ5kp# a2HKK#33h;k6{UxB{0b|A.Gؼy3_5j_kk+o .4@rn:fϞMzz~=^J$ω'Xx1&fje_ oȌ !<؆ߝLDGiʖ6TI jEͼ ]PgL>{nCn joQIAA[v-PӧOS[[ˊ+ukFjj*&M1W^fn7L<٘q;f1ȲLmm-'N`ǎ\., ^x Ǝkl/Immm/a…555rJxA{1{lƌ纼sN'X$IbϞ=q=\q~c;t̮f(C$ ~HĈ pܝr7P%4d ÆOyo#s^[ڻw/?P[ۤZ%  FwKh|IA'N IDATϸq3fTrruW gܹdeeu>Յx^~?>Ϩa2l6EAUUbcc#Kll,ӦMرcl߾fΝ;~ϟ?n#<ªUPU &ٳ9tPMumFAAmMx꡸nJJJhllӧOSVVFkk+>NLLQ%44DzFt]gʔ)444piz\ =%nEqj6v>E_C5*xe&]^4"e nL<أ6ynIbbbp݃0@DCAA<K $Ib߾}{Ƭ~lcX"/w^TUl63|&Mdc]줺Rv;IIIx^L&&ri!@O>#GHll,X,ӦM#;;>OIII躎f㡇bժU(B^^OII eee$''Ƚ *ͽmx<:u={cm~eY6ޜ9s> Y pŋ%!!EQn)"I-7 22G˩zR>qdM<'Nq?$Y"24Rr1&DSLrOYY`! AAn;Y1Gk$ .Dbb"j*FɸqDKK ?O9~8?LRRQo۷c6$vdY˅EUU|>qnXcZZtvvLvv6?~UUq8̞=<@jj*|nǏ^xQFe˖?mmAAW&55 ݻУܯ[foߎdBVVVEQ 2f~理*ؿ?L>zh0gv%K{Mv&!$ɌLt]K =(=%0"jz  kǍBO^w}āؿ?>1Ȯ?!~Əσ>h +++9t$1vXBBBe7|iӦI ػwQ5Å 8z( ? t/Yr%555Ȳn?99Yf =QcÆ j/GERS?ܹsFFF7"2]]]q)V?0_77C$֬YCbb"3[,ˬ^͛7v(-mM^u:zX   ''.\CMM deeQ[[իYl&ɨӟsΡi3f`l6ٽ{7deeb1#'';o8|0N(r={:aaa1vXinnFUU;F~~>8dYFDmƨQnyƵΝ;Yd-Օikk7%uuu3}t&L@RRf[^/.Dtt4iii$$$ڊ̙3ڵ8Fy1uV233YTVTTDqq`!܂Ύvû  0$b;!)qc|G-G}>odرw}X,X~=QQQL<cA[[6͘[u PuE!66ロF6l@KK v˗iꫯe웓CUUUUUHdmllA$IJPPM… r1yd,YBjjQf麎b!>>{x{g←#&\8~E"!  veeeҞt8hnn&55(VGFFݻYv-3j(>389¬Y[ZZl75mO%1cƐ)//pb N1c1E1_hEEEu3gh$ij>˾}p8<ˊn'Y=z4K.%22/~ ~ox&L`=ֿ5NC"!  vo+;vHԩS4 IhhhwAQwVO?ԩS[𲵵zS Dhh(.1m4Vի)//7w8QZZDDDp9y˪jkkOee%qqq,^xSpp0'-- YywQuƍGyyXr466vIAA $`hiih7RVVaDEE~E!++u0$I`t]ɓ]:AAAL>#GPUUEJJ SLA4^/QU~ʔ)l߾h;c n*$ ֧z&</Gt2sLP $r^/׋GӴmFuv;3g$>>Mȧ~ڧĔnt.44C"!  vU(Bmm-]}sF">Y1b'NԩSՑs$hv5f3IIIx^^ e62e v 6PYYilOcc#mmmNpp0}FL&!!!7p[j[nE4,X@hh ccc#vb֭:uJinn2=ʧ~;O뮻 B4~99*f>w"  m-Wvfؽ{7nyQ__Ϲs;v@4v;:tZ4b'11NvL&Ξ={ć넇ɑ#Gf!IGfQVV$IDFForaZ\UU"==*8pN%&&ryJKKe4fرdggNRR"5GFFѣG+:111"I}'O5>'J4," O@AA`_zjkk#55)>Ç:ӦMUU"iQǏ'++ z^$ƍǁ9s*E!))dfq~Y$lBJJ #GF  !!Ç#2N(z;_'vӧ}ٲeXQvsQHHHRRR;wn!0QTTDuu5mmm$%%Q__OEEfcĉ),,D4֯_O^^^dq•E1fV DCAAZ[[oXNx1bǏ7JDKK KMrֆd"66vƎ{K K4{6ӧœAAACmm-9sCUU@vfM0ZZZLٹs'DEE] j 55˗#˲qޞGuL&YYY3͞={hoo'!!CNxx81㧼M6o~ޫsz;,˴ vIAAU=;Q`0^^^n,$C( S__ϖ-[lDD6<x<RSSf5&qrz($ITWWSYY$I$$$`Z455QYYIqq1-a8z(g:oiiZ R{CeۇbtXp94M#$$ŋq:~9殮۷JII IIIDGG#2єi'N`ʔ)7<(|>BCCo)ƿu,K1]aIAAr\mz'X,Ƭ t'BePn7~<eχlfc,tFC̜=f i~񐗗ہ,TTTZ644/-5Mva $4M#==݈UUz=ciC.1 +,,ŋs<eeeȲLdd$躎ɓL2W/**bbuHDWW`! AAn+# ^Chh('OD4)t$ ʩS={6eeeL4Am`vl&..8dYf5&"""p\W0͸nڰᠳWIj|DGGP[[v3sLF٧8+**(**j2iҤ^jQS)))d21NUU^7(IGsw@oH  UpHˑeK$IrQSSC^^ Dxs4M3tvvIgs~l6DDD8$I"++Çj۶6:;;¬TVVx3gMu vi&S߾cNOOgܸq(ӧZ=0\i>|3gw*   m%fZba>,,̨x:Å$I9UUiooGUUnťtvv뤤PZZګ {H,?]%66bgsMBB,s97Jxz2Ax7  p4UUILL4j[@;P4Йeuuٌ|>4$cI8Nn7Off&wavݘMQWWg,ͽL[j;i$4Mx-lA$}1~x%w՝AAAj5Nkk+6Zc;i$|>ttt `$kTU5L8xP~?7o=픛KQQQ4WOdd$fR^uHo6{sUII zA %L[B_lIA%` 3!!!r>Pƍǎ;. j҂(KwiooGQBBB1nsX,68eYfzj}k& BCCj&L@\\ܠ' t]'""\ۇl&33GTUe˖-cKh&!{KK8  ,e` C455 vCVDD 4773|f3'sNdYYV$TUFdd}$)#)) 6ӯצ:q1&LpNVV[l!&&!sE!<<`|>Ǐ涛6mbԨQ:M 0o-k- 0LtK5 ΢E~F{{;L&.85J^p8>}:aaaF#GOjժ~)bzfϞOPPUW^!99~^lBjj*QQQW/Iŋ[~BBB; a  m裏RUU5,g HF[oe$NJdd$nǶmp݃IdH9qd2a27o1!<<Vbҥl߾_5Ɍ3mf(jbŊ+$={p ~#MӆK=DCAx3<͔)S;o@qq`0YV> illDuXd V˨Q8pmmm~4MM$I=~C`ɊvillC}vvÇ)))̼y"YYY0v`XX`~!W0@.* VP0BA 7\GG>Otq]INN&;;M6裏ig֭ɓ)++n E!,,#F}[[ٳginn&""׋d2Bjj*aaa(i޽Y fٲeF,nvJJJ7f `/_ΛoԩS6mZ3V.OlIDyy9,qFXl_koo'%%eHz0XHNzz&qg6)IJO'}H"zU͋.w+ Mkk( $qwƑ#G$ ̷mfΜɱcضm[NJJgȲ%<<1wuuS__Orr2?яp:H&((Ș2躎ngɒ%,Xwy***5K3])--%33+V0o޼I 0"jz0"3? s<2#/K1HA&| TX99[+8j'1.:\?[f$2J%?~~MƅtP|MBF:‰H QĆJ4ǩ/&ߖ.]ҥKQEtIYyGxw?~<o}[8N֮]c̙Xl6#InfW444`Zq8W-:*I |'2c }Ycfw> 4daNXX+V ""͛73v ǡCxC7b̝C$=A$ c?j-cP""Es餏9i_)Zu8RG4&+?-IoRs3Z2ƐzM^$;IS333KTIAfPUUEll`2麎(Z Ƙ1cgEu֯_Occ#?AAA˲̈#},y~$iUUU|G4773o}:1gϞ%33sP$"FIbb␿I`&׾E b~ CF~v!yv^ޖM桽 -T;.m-ur0$ a:n]23yJ=ih5XV6rUu@N&+f\:Hfz&FzU95OѤGh2#cqHC}G;i>AnҥK]l6cQVVƺuphƜ9sx饗(((`ڵOvzσw]4jp/,,w{졠_|sCQ$IvX$IBg'OG$Gunrrrزeˠ%>~?֭cܹP'IgϞP$0i4A#$ ؘ8.Ș}ae"-ǐfh~4n`PMlsTGt/BQP ]1w} /iƶmp:wR&[($f&"{k94 D6)4wHF[scDoNtlȖFB*p;w.۷o'::Z HeLBjj*k֬!>>E!2sI6mğg9r$BKKu\&֭[GEE,]ロS ]ש7 )) &… Ytiݒ~{rJxQ &[QQ}Xp ^JUUvng;Hz0>zA9} =5Z:ѰXȟcaI7UӍh\֯7NsTgFh "!& 7uAK_gf̘1Lg_Ntt4O<ˌ?ɓ'c%;;z'O}vx<477s}aX9$2:::X~=~fΜIpp1Be8p̙3F/^7M^~7#<m֯_ɓ~/KYpua@?3w^?EQOzS]w+++cɼ{0yAn*1=4^t%E`ӻh2~oGt^H]Mػx6} ;8aQp7ZYjiݛVf{Y~Vˬ,J+5r7PàrARap|?3|]fS&DZ1mSK_qu(i͛7~l۶/7nL͚5V۷M6瓟ٺu+III[L-1ͥI(Iqq1EEEV+VРA<<ա (!"""""66ݻws`IIIlݺMr}q{اz<{AXX맧3{29p?ŋIΝ 9JOO{qu"Jz9uu""RN;vi_/ҧOԩù(LHHHСCoߞ pB{=W'!gaDDDPn]%?d2uVzK0T xϯzyڼ#Y#;"*-44%5 (( gu.}cX:v>b9˻/_NXmX S+p dggP4ɄfcΝlذf͚GiKNbb"Ν;ILLj뫩bgQXXȚ5k裏\Tcǎ=z3bѩS7ǿ-9ޫ9_bWnPDD ^jQO>B`Zs+*Ñ*@I9g2-"RiDTeÇ,WRf3̟?Krm_3ϸ:4qcǎeѢE2gVZu%?N'gwu(RE(!L_EDD| 2D\Jؽ{7Vb :ӧ3x`W%ncܹt֍ٳgn:rrr.Gbb"ZbE%=DDDܔFIU7`NJ+l3LƜ9sp8׏/n%`ذa̛7f͚ҥK9vaUd 6`63fC*DI9g2-"RiD\ N ƯJ^^<<8Nf͚4hCK?Η_~ɀHJJbڴi9rĭ~ޖ.]JddvkShZ9gCoSCDDD[0t___hРEKz{%553i$-ZDKիǖ-[ I&xxx0swq/_N.]xꩧ\TA0E}435_~Ǫ?49 :I0?~W}G /=۝6ۖpwMW`jVsrx&}v7&C̙C5ؼy3͚5su8b2p8ddd'ݻwg̟?ቜѤI1c,ZpիGj\Zfz#ە< fYΗ hK#i9'oaoHvXI; j5ڳH0 k;b[vky@~1?I`T^w+z3?sWG8X) 6DYĤl.|9:g;#Gfyp:ìʼ{"""r&cǎe̘1̝;;Jfضmtԉ7qFW&r^yf̘O^^4nj-qF9Y|Ñ*>ޭ޺iK(-}8gj*.o'-caտs3x3~2'Ežw_ki3Cab/ȢVyILV=q1$'x[o׳sNp8غu+Vb˖-ۗ3gϺ4. L2&Mł ذa.d2… vieRYh`aɮ'){U#b>5FZF &\BZ_T[Ӵè^!YNTMCoc&WG!rn6~aϟONl6Wxd2Q\\ngдiSz͍7ȷ~[틸+Rzor-[F ۻt؊R2nw^K5LJJz˛o 3ѵhBT4j;:`?|f [4͇\yޣL R QHR iA b0O?#&DrEDD,ƍ믿f٤ѲeKj׮bt^vJ(((`˖-!FrQOۍ+X8u+BA,~p#q/"dŋNvv6֭#?????BBB ϯ/..&--All,ڵG%R/"_}v*BTTAAA@v;YYYdggCqq1QQQԬY6mP^= TTIzL[}ĦbҌ>̄]v9<X[TtuOg#9lYQ_/|ʘZ3bscLfm5g3qf6Kglw5㡇Pu%e2;*Of==͘; y:O9B$P#Fpu"wD OzX]p%9|S:j܂.mYÑbMw|^fMryiKM5#66j8nڑãL>-3L-"""rGOy'{ďdGTm("R-v///v{pu#EehmADD.W+\QI[֊He[֬YÚ5k*0"ʥr4EDjӈ<)!L_EDDDDD*SCDDMiD\s/""UF䉈ȥNI9/B-"R5 Mi)!ݍKCoӱucWc%6af`ٷxם.P""""""R5TJP4$q%`,ݙQ)Hrr`LX5]o]O?DXp AXYΟGd mfW3H?n%snz0 Zr liyguhBUrVn$R l[Ylۊ$&̌eOՋY=.ތ/[Ý' aMW6,4ם\v/,ۏD!XqDޞOv{㾐xkΞ8:<Ҵ׫oiIgCk8%}EDDDDD܎LvS̅]A\ogtُ!&]=x%PI>?RTl`2{zb$-˘ m` 5t ?UHFq3F- IDAT+H$>]O/{-w?y%Gj7+banJ ;p} 18v [y>Zu?DDDDDDW\?DGG*Of6؊k dVvl_#&..;\fj=b!0g-8*󓞞~(%%%l*e_&oDDDDDDDD""""""""R1%%=DDDDDDD-)!"""R ,͆ɼx]D󦤇\ܬW3z/|<.,M:ڴm,y̙ #[}C<#'K(O֫=msso9O"""&"""7^ 4ZNifV\vW\WB<2;X\!~3QfW?L"""%=DDDmy5w_Mz5H߾~ʲ ,u=^n<ЦYNs{Ư6)eP7-&ʄ;U%kt]Bؽd2o7sӽpyQrrt"""U]%=b+REl6W ""R&SZ-Kge#fTp?g'oa au9r0>)}''<z=[< epEY\6mgm-X#OMӶ80a mD5a`a펵Iio]b]Q-y.3{wSo|}!{ǯ&B<~I?WC}{6]^Q)9"""UL%=vHKKjuu""rzxwVj9MtԳ,気>c[UTGv}$nI:WvO0o ymS Iy&ʇ?`>Sۧ0A^Y#k8ԫ ;XYXw[n][o~ p&|Xri|K9֯xoADDu4EDDDܗ%>]#V/H` |Ts(;H0/5gGv?{<~ɶ8kVtxeǖ2:y<=OOu_I.4uu'?ABb2=A ;bYkۋ{RCDDDܔ1=1c˼9{l?ICxⱛ-l,RW1'.5G]}w4S6]5 lĒϷ=iqǭ/s1Կqdފd]ݍ<[㙓x7ߏxϒ*1EZ'Q DDD܅"""Lh]k}o36_+3X}Ӻ%`Hw<%isntt!;괤uKzdl7lOx2>l1+KȦi7KO"-<|k,?by8/\7;<Ƥ?=cۧvAa29nYb00KI6G,]-y㧇kI\O`'㘼6s=3Q42G'&Pt $yPo|/ϧ)n("""""" OzyiG(LF>,MNhɑkp N,x rԣ덃H u7a5 >Ky^Ɛ涡:uS@q/guDtڭ;pY&"2WHv`)Hbx]$_؜գ"?܉}t{k#,: bKqeB>xAtj%gNd׹> ։!3]?s)aOЎLKca.[""""""R*eMVKL>Ql hrKӚ8n&`Y?Gdc?ˤӔ 7O2qLYUH!فQ'>&B,XޙBg䀿$6X$fmQ׫ؒW:2 c !6,O$[7Appk'WSU9Y{*tRLB¶wZ:/o7>tD}ʝ={p'2uVxiWi߸!^k%wo)VQ˱zЭg?{2swz$VYyCa:~!E&y,""""""JKzX[ӹq0%&k4%H'G>)˦dz0 X>%;7{D\~D|h\ Ǒ4(&""""""'-܈` r:U%].KgZc-} vtk(=IQՀ[cI%}WxNG&_ۘM_˦S,f\7j$y\f7tT10› ƁYz۳`ڴ3m#<+> fM? SHv'dXO?6N//tiEDDDDDj*{Skn[rQ3mO̿k ~&`xh5}lg.\N"(..;\fj=b!0g-8*󓞞~(%%%l*xzAޥw)821uۼ\%%=DDDDDDD-)!"""""""nIIqKJz[RCDDDDDDDܒ"""""""▔d VԥlADDo=JAANաYf|||6*,cGRE]ZXVGˋL&0 Nff&҆Eѣxyy驄Ed2퍧'G6^AAK ` IAAA\[I9NH [KIqKJz[RCDDDDDDDܒ"""""""▔ OzXj4Ctҙq6h#U'tLTt$R|,Y%ciLxDҥiM74YR?Gdc?ˤӔ 7O2qLYUH!فQ'>&B,XޙBg䀰S^1-&(Ĩ[ """"""UI+iZN{wCY8䵓ë)*d:)N&!aEK9-zrgDcLUGiU7n״K ף?. )*60=Rfǹaf4:YRDDDDDDJܲ ?i+)Od9ӓH,kڃ\,ʒ=N5&0pb˻{D\~D|l\ Ǒ4'yٚ[#$%w66%Ǽk;:)""""""UY%oGp:Qݘ} vtk(=IQՀ[cI%}WxNG&_ۘM_˦S,f\7j$y\f7tg(1b_Bno'fDDDDDDbSIqof~vqs₳$gDDDDDDR[ liyguhBUrnd3ٿ;L_!'ԮA#س7ЛЦQ LMfCb*6eU*-s++R}[?ĄIz9GśEx !*FX u\—㺓nㅅ6|b K6Μۓɮs}bCg.c,LiXǘ>gn0g~ ©9螈\T*=鑟;vaEE ]-4YyzmG BWУeM|JG4&gs҄&mՁ&A#lYF WKӚ8.#"Ty'{i#^f3{9v2WFdt>{k/ux`OLX8ZCoĴ%AQ gg‘JZVq44[$0Z,ymyAqF66?G9VE@h >4oQchE51&ouc\ϓ`FY~kHyy`,\yuAd f'K9-zrgDcLUGiU7n״(bd- XW+ 1"""""".޽ńl:`IzKQ  D`<`6cvP0Y` GVHr6a?;SOs{mO"k`99|(S jrO_HQL}FhAd7+}A"sTߊJNz8X#6֊>W5'Ç:؂٣)!^b6c„ĂNa 'p^^\,ʒ=3^c"8m*ӽ{AFV.Np̰ T'<#isYc/͑:# vndJ xX EQQ1be°t;6]iTpr48V̞aoVci=ҫ;Xݚ΍ҙM;Tqaюnu Rų')^p },J $;붢}kٔzjYl8F$ozج5\kfhp2wG :)xj6YzoDDDDDDU!M{qM?K SNxx^5O: 'im!D8dThI /+ZuY<6gkKa&Yl#73c3a  H>V4ZF_A”'~|yk+)>U˸YSjԤAk|cZ>_oW]({Skn[rQ3? lŵ[R2ppPd;N^A_Oґ"0۹-9n!$HHa&Zձ8MkH57\рjgO$Tmjm2(YTりeǎ$W!""gaٰZtnZ#%07G%"""r~D^0r6 eWrfle=Fβ9Orb_^ej9*"""""""ntk\%%=DDDDDDD-)!"""""""nIIqKJz\d,͆ɼx]&Ws.xu/gɈX\}7`"sp/4E9IIcaEaY0Giml gך?yjb^k`䤒|aSGFnf [ I.@8\lἠF~8ͻŻ tVDDΦ’qqui"l6CLԺ)^5E OdQ3:g>YNWX Bˬeԛavl5iwex%c/\~z?E2l@"wwGy#> Ief2׏;:֗9/)3?2ڃ=.1JxT KzؑTQ* ..0DD,.u{w7r?ʔ皲ywc1ě_NGƛA/lk(+y }e/?-u1r t@qVeB*ؒ5.^y^2[MW_o- zWf蕻yT[TK6=hr3|܋5~?ekQGeXz|-c;Cx~a8͗[Lvj >|)1{q6ٛG1~ԍw>85t},331 9. ->X`)y}`O/!2Q IDATlX]}D!xdO?u#9Qg 9xJ\g~pJ£\L!ԫ}?|S4e=yi9Ƽˏ{C\*&B`pm}">%gSc'_Wy|yrcm[c 5jy=7V~ʼq=i?P!qRB! ME㋁1:t; E=)k{囮C.ccxig tƽMʃ=‰iP}QqU:5UĆG[R]"{x MU}CJ^2B|4vA'kS84Њq\OOB@QaZCmi{冴k[=sD"Qr #b"'Ft~ B>GC9ʫ#d\9.G"I}Y5S?!Tb=y_B+gķ *@A!tA.J#It2"1Ť5?j^scS!D+ˉ>v|˔~HID!IC!/ ~)l:G̟_o`̄dBDϟPB2s iO|7r{=]6,@w;>\c&&DѽS[)SS 0ab[f-і>ͽw٠ΔӬ5#q ?睑Yc'kGW.oǴی60sF k1-MtBիmR*Ӂ1S;dGn'ꧩyoa +e!x̬DOO@777wsGcB! ѧp=B!"$$$( D^ʝѧ Y!B!BxC> B!B!Ic.B!B\B!B!^JRB!B!KIB!B!x)IC!B!/%)z!B!$E!B!B!B!B=B!BRB!B!^JRB!B!KIB!B!x)IC!B!/%)z!B!$E!B!B!B!B=B!BRB!B!^JRB!B!KIB!B!x)IC!B!/%@nϰհ'+k/=W>ij QuD{cB˃0 :!BAVccc}4etёߩ)7M !1!')S+G :ccB//gB!HDD...~=T%i;SFxaV=zY0 F 4jݚ2lǽ֟AWwy LU;<7kx,G>wz֧3+مMOaޱhiK8Ni 70gW{D2tz[^)sFp8E|6osDO㹣\:Ú< }9KTiW \OÜRW8| *Q&{-j4ֈ x;ɀm PS_ÿ.cEnp4Dz-kO>o䞗h,Ӟ61ys8 ۟e,QeϜ1+H?W0{^>U3K<e-lcTjIw̚'ZyIrE]گ 8iAuq_ 2sQ޺Щ2/}T؞_+iyI r_0},wm$sB#VˡڧB`@R(rBQT<A$+ҖYYd&CrgNqf**UBN:.J[Bȝ4E) sxvU8qc[_bRuK Zڼַ1YTH & 8@IhRVݹ8*FvV '8{'ŲeX*4*s߿OZy*8Bnq+$:EِkPiБ-A[Df7CMNll(i< %UyMO^2pzTh`ke)ե>bkr+(=.s6}eLFo2}ilU KL'M 2v!B!(^{~ti©TEؙsJ*II/}8d|:dG>\hxѡRur|.BT#*DΫ6ZMP)~É߰1$/QYi;0[[$T(:j4&6E=q/g'f]~w'b RݺY/ޕd.o}z@eMђPu!{#23ߢw 9IK 6 FbPYS$>][$s16rr(~g>b |Yh>6&J\* ,.fg.|7s۩ 1X6QLMRyŠSx'VvW 0ɲ +j;k١˵+Xj,_ی]z}QWت|ZhZI%9I~ 0ϸSՀ kˌ{YTV8?jAQRH|=T#HS\i<٬m ' N6> Fd*4:K4B?dRgRQy^*IDGz<)KLŪvtzQH)<CI6gkΏX~85Yb(BkGs1&1QQ:c%Bɶs-;G rl]!B! @=l[׊r!Z' $gR>jl+ӼCS\ 3ؕ^GcڷO]I%>erMez47BtmǒԲ.Ws18zvj2Tqߠ:x4oE V Y5k3&܍`R;apa,wm*O62 s{)B!ә浇S7#ū\n++XVƷ[ uYT [WI̋ZQQaNi]L}Ӹ9yn{3/Ou%l#+`R ؽC hKXD&mhU5A1|Ǐd2'_ Ǡ8D~9=^J>I=YB!BQ ѼU#ʖ+Br$oAڑ:&PnyKsJƘw}r.(SBt#Y*tyc|&r6fA_~PEJj4I 'MGg[S>yr25pZ_wj_OnljVQ7J|nsJX^{1cǦM}F.N3ZJ ;k̢AU'JU\fNvLy%(4W G|%\&呗%:Nۜ}(Wwɼ=-c(&N7\!wBO~߶kLcxr}8}kAr|z؅B!`x▕OiB%)h:1лٷz +O&.yoEʃn_<矔[yPaii*?ODOiӍ7nRX)Gt;V,g۵xa~{%:x:ݼ)1󱊘ѤB)\I4 3Hv`lۖKd I1ܻd=+ʺa&$k.fWx>03bcӬ d5#fWO*M״y )ɮG.ecubc`ܚO>S-= u<ѧ}+T0>Rrk7O/v!B!(f<==SD~+r(s1T{m$8;fٶ4:Cƿ˼+Ͼȱ !^˟*B!ċ*((%JHHHP@@@LOM#t+݉_SDyE]!BB/W/rǮZ"yz.F>^؅/#˲ ԙzKQVO㬙 e|֦;uઉ6 p9?AR =UB!H.ݻF 6m!::ڬv-B!YghZʣgVb*:ӽ5ŏ#\Жb~Nt2Unz!xEGGsMZjEٲero޽f< Y BTe*xW';)1G)֬:g"3+Bڃ- }B"8v8-FQrEaѢ;vD!B?P_`O4ۢU6𰹴8`5Et EI,L!c 6*xG۞rB!_R4aH<…G!>! {Ǐ=8`I  y<BX=Ky+x!BTŚ3˱wfDm s_LP¥Vw8x!.Bh29Ɯ)`B!D\\vvvf-݉)3S>"E/;$$$k?Z!B)^{ZS깳n<#~޾ ] O:?ÊDaoB! .B!^x=B<*B!^4.!gmmMjjC!O 55Bi[B!x988Hbb"Y#B3 HLL޾P!_oB!KŅu(B!0-...־=Bpqq)?Bb)Dž  Y!BճVt[(nʂVp.jtcp4Pjqx<~GRs]N!ooM]LJp_̙'[jzjdnMx>P3~W+wX`xXUȈ!]_biD8_?暃' OSk2uornqi0;Qdza8qGǙcu1zxWz;K 5̛+uW]; oּ䵤ac[>噌[ph$|v ب@Q0%vKےHʻ !B!svrpܤ IDATpoggWFCBBpqq+'dT^WTTnۃ#ٻjwkb E^-qw3M@1@Ig]KrQy 5㡬0 &uRȉջw l7LҜj†- 4S_c=ctmՍǸox\IsbӶNkB&ֽ֔7,_{{hsoSmӵ-/XQyk[t:%}Ju$xzWEdݑ>(S]tȃck㗖t;ObЋu@av ۳C!"YyPFF6\X8Y8`.tƒms-uh4r6#M޾TՓ[rj|=h~b{=_!1\v;êp&r4kh~ _pA-[PQ\2yDW@ӊnئsc<>&RS}}D[*SCiþKL=cj&vܷq:Vے3f);];P|JJc*}غ?)֤9-01Ge] ߇F\ܖi" `Ww#9  eq¾ӹJ`wH~9{܃{X8C1`||=gl7tؿ GC!1"dܹ}=.Laǽu;/s|w:ӚAɤk0uʺM$.Ϙ'-!Bd3=jWKȕ AjO*մ̈ƉѼmO+eeO\>ۋԯ&1,Z;ǜiqkG>r5,IYyk{ڡlżkY>e~}L1&t[s$e*xNv 4<}5嚃'݋O ׵\[+* _gcs䖖C`d:Kl[D̘reR/0͚òT8O{yv_ Fր*[iG#D1$pnGӆS%l?M͟ }dhtmuQq*Ԛceb?Ee*$kf֢=D~.B!?{JwzwE$>}D,H :Fv*P :L:cm|;آіIuh׿>~vCjr(glh3=`¢s$|s1F惣霄v V x[<:]k_scq[?3]yms11Sv"]Zo|_ʵWMT*;5yϱ)Xd߄z$i6%bY<\};ҰU~v>B=ЕY _jjR Ks"ol 9ʟ篐 i+XFNDӸq4dQ{u+&E ULAօWgD)XYۙnd|uT%+T.Λ6!B! S*zODE 1SG[H!4An[i vTh؝Gcp;c⬟D ;l5eW>VczⴂKnh $aRI+Bɼ%RdީƖY~8TE KTZ ܫ֤Z?wM_}|3%evxksMB|b1z.3D{!7-brn_:>ix>hwCSZ<1)9o&~Dz.`FJ0?t܂.wA:S ѵoNX<t$rJ1<:E2i *whh1RDx9+Ȗ":>'g !B:TmqR5EkW]ϕsY[K~%޸^6}l^m?1T\Y @Z2I)zB0عQpQ?N0Ū[ǚl~a6_,V[3g͈qsWN7ST]f~HGŷxz^~f}m{X䶭&}$py4FB۶];D98wcTiowS㹾oEZiXOhdl]7g[AxFnXd,1 -ZJeG&3~ W43NbP0Eg=^ ‡]]s߇v<]!B}𦿶MgnOE}%:LiwBcӰl@>8ր^ma&]h_0z;Kӵ"qg~@=k8?EKH-gy)"af<>zK<Ӿ:5C'՟.+RA}?UaQ4q \M \9dkD^~ZPg\1;۶2LR.Юn "AD\6 `rr]'ñ8Gy14uk?E$yWDN )\ѵuÉҵiPWEl).ٞr(cjyÿgUO6F™|;k#)^m *6nC )oCڀl8v˦Ʀf'zHß}}Ϡ-Cƶ\{y$"P/]vEXEx$ۢY[кuK(x>}5OtL6ObbgGmY =v}RפK=k:K'd瘞cɷNr1څJķ/k{y3r,*9lkshӈТEQQ q6lCǎ]<ӿOg榻^- *6nM(oٞxpnEQezv[Iv;kxnAۮش nQ\;t @c >jhح`ZTķO#TlDkVhTҶlZtHxpQŨݪ[צ* qW ڄv]:Т *{QDžjHAOO !yeO֚ug'p*T0ww!xXNe$oʜ t}W]2jEX)pujԨB!!$$$( D^s"4m_ 3zk\ R^Z?,B!B !!B! = $E'?c?B!B~V!B!iB!B!^J/dâ[͌^ j,޳靬 ]|/ʚY(oCs<{|AgA󼜫5RP}o;OR9ϳM]S>k'Ģ0~ƻ@,qB!x<]|j.gB]3[?.g6fvoXuWݶ%o#5s\8T?;=Y8֪BGF3k7szV<U ܶ*?ek}r}ޟZv=}n\?Usۏdl߰?F _ 5. ŢUlޱui*=eC0g~L};fּC B!(pOAJҊS߷.318-FQGl ;'3V4(UԂ'8x- lj11JBdZ!Ț}Wo%Pf=_OS7{NxF(V:]ɔb1y aXҔ="H+<w1Qe6؁ߤ̟ܵ~ <ѻ|v7?k:2ДSp/~z u!eOķk?_*>7;J6y?,&B! S.z8ڷv{] s )}t;3ݰM %+Kh vwd@.B}hK"}hTm=mY&k8 uKE,7/e;ta}J{㪉|.e끮kLމ:eq&regg }gMW3{s ]5}6빱j$T\mK҉*W=a}ǰyQ]WMWl(uiۨ2:^?`Q{8?~/"P{O}=<7_Tćt*85HY8ٰoBZ)z~o{w;"|:n/-QX%rqb6A2oZxg儢&旑%Y|Pjʣ #ʬVjNʘ0V5o~;7W}Ȇ 20`,Ѕ^Xr;\-|2u.Ϡߔ]$m>cŇ}C}Yf¨>7jƱk e(_䝏R6 [ę?14nCyJU.L[գ03VK1+n/Ň6#1Kj|Ql9Nq^|x:|̈s5RJ >T,=+PM ܖ J6~>?oxz |3kQSrdtmKڑF,n6OG0Mm$bk{ڡlżkɏiGw/R#@zg 8ګ36F <B!/x-\f`br&ԗ>-qصo:`_;O?̢9 qiX*; !K,a/%O$puVnMNѭ D<SH^\WIU[2BU[9bE¹8Gznlҳ0;z["X)JӫYz‡7W†s\}KϺ\>'<~D?qcmfHOp֋iڻ ٴ'G]z)o̊{X^vD_ήlDȭߩןl*G?.#by6v6>3;NیM})ͫ[sc5O :Fv*P :Lkeݪ[5~ ?`fʬX%ۨ='&%Mp.1Gjkm}$?,t90k"]Zo|_ʵWMT*;xo{^Ū_7r" UƍРwd}OI&KjJ7@"WcE2fVԷ-lX6Pǔs%.?͜/kV0a9ٌۦǿHϷsޔs !BȞ^CS.-+bea}xYoAk(.)Шܟ 7yx! XTU(Ͷ2i *+GNnh,uU7нqe9RZZ3iaF$ěȁ!4ZГ':JG[H!4AR/X@Z7m)-F1ѧ-L ;w*4ۣ1i|8o~psڰucchukW2v#'Cr9ɇSZf"=]g0F~O%\z4yk6{)G{̘y|\ͷ>B1OjĘtwBe%Ss>='2+>-p7T4BK9gk'T)gʿ\6u2(bJk{՚T ҝ!h)Q 2?OyqA!Ԋ5;3+`'4y4o̙DvI X vnxU]P7g[Sl5v೤JThzh(?>>sA}gWM 2ާĠ`@X4y;ըUuѿ*{^s Gc`PRs}?uV>Nonl.o}>J6tC}+j֮ޟ=}QmGnӭcKYV40Kަ#cKyaya@nc'亍=8v0q%s$9-Zu~XyT KTei'2Wkv8bg!|A?F ĩُQe[cV[f#dlR$㟤>Fdl_yc.99WnG*xo/e} kQqQVpJ!/r^8jxټi3gLz}-¤sa{A!eV4ؐpl:5E{^2~(!!ڱ"ԧcG8Q`_6 ꪈ 9ťG*υ^#(֟'ɻ=%rrB `/z \8LX`PaVV=3m iNc)~HlCnh ĩAs4XTȄ sSU ; ˲W gc|݂ϓR-}khGc3x \uߛq]r(svOӦ.p!ףs:h+ϝ ζݾ2^Jt[߱1_#az [8CٹۍЯȥ IDATƦaـN5,}\9ŃrC_+Q%|٣阻^{;gKݥ!}2~DiKѸ۹u'wJ\|p%%z<֯1Ff F 4Nkؑe8i֔L3繹sg{D.m˦p\3#ƀi,'tPM7}l9^(_"\Gj9HD!DDe<_Wkfe\^Ic"ksu瞇-#%kRB!K=ZЮGvq<'+>ynݚ>Ӿe=5Pn߆}5Fueʴ֜_{܄!p-_Ma i8>l Vq۽B-id|r#*a09bpM>ifeCԔl.[=J:w͐Mf~.LJob¤dB#x0l|oo%pXw:G\uFn#8DrĚL}C b8sf1Utcu9OM?LZT4͔a{2ΐ@ov~5"~ùyzE$ޯ;9|?UαwoL>rDvWNwZ!!>n/ OV3@sc?v-`;:7t E)A@AAT@@QW Q A v E. "%H!}9i}I;3n3Q1UujN]0&sZ&=7(O7O|}pJd>-[cd <#6N-II;')%TkF&9T/É65}6%i""ەV#[gB>Wd~dOJ#1Vk&[I?M}?HfӜ *)S;Zjُ*<=e#v_>u+p%gn'o(j)c9d4=3co{I.)ʱ_cm(*rkL]z2pqHX;vڵkt""""]:wof[ G^_2Uؓr[S2iIQ{u """"=2ڂksvd|3ӱ2/Տz [6n2sVԌE|>Lmk˟ݺ%"gNL`,G)myٱkVkug,\,byö}Ji$+tkvdleE<]{vF.Z3hLXMX϶ &4i&[~bҶ*986llK~/P3kj6ŏU bD{Pɳ1DDDD((5dĚߓpgDUwsw)Q$1ҔracgJݺ:&Yx2 =ǼEz>ąܶЇr`6,Z֛ߍb{?_ι{de_yͦ-[ ,;ǩ-\iح \ٺl=Ahl'^ą>fo&oH-mǻ(w߭!  ]ƖmmExxF=v\,9l|?NDDDD|+z3{NsãFumc1ns3x;;ջŊp L!.n8qv]k<ÐA]x sa6͞ά=wy:`kG3Vw [[՗ߠ{{)LclC^Dt[^{ToՃF=%g2cxéZ<:Jþ27tf.\ CX2ԍV3 =?8h,h_qN߸Nƌ7bՕo<=Htpy(}V]9|SH/)(ݼp2Ϗe ^<; ^-+{eP6Խ^xla9В>'}ug Ba|l{n1{r""""-gz8xSY6T$)x-`\js#&ordkDa|0dsޝП*.ዥ~^>~X2[uT?:Kt:Ͼ:k 3M+IXbL~uz6aؔ>hTJ &q\+ǰrgِA Tu!{îmŽGԳ5pJ|0r|_ZżiǠFGz?@MNbJ"51&Iɟ[|i5C9[G ]GW&b2SvDwն\pˊm7U qCVNw?gXR{q#c$eJ ?&ck6nǛ=ǹaK8opmǸhmGe0K9vLLiţ K0`0neFZ.TԑK08<3dnMjQ o̪ic|6#} ai:~"6OǞs-i9& w4oّ~_O0oMo/޶}cHH"ꄧoMs$hv :7CwWܛaP"bRyQjmS/3n~6ebKbX V.)h7/-KyUN>5\%Fp>(լݟHn\KZv~j*֜`9G;9XҹStӁK'r_z y8L5z2ǽ}?!?PAtgnM>\\br`̦]woDsa`s6;ÞqӾ0Unmh~_%Q2QL{ zumO떭p:67ñ!ydYVbWgYxxwkMy7γ[P\psuj $x֧ު4'eK M^o2^3:IJVD٥p<2ץL"Q=X,gXJNx C٤%<}Y^d>S[D SWstKM^ҸXs>dʪ n5w=<\LV!u{ɠuaNB8ܒ̮-~d℥ј>C!o ՚ɖE9ȳҕ{kqP?j^Lgl~8c+OQ,6F }+}e]%` wȳ=S뢞 \7REyly58oML<6v8N MyGP>6Ώ;FڵX""""YtܹsWȞUS"Bwꙏr4nډ0k[Xڕ<>vS4(ŁŴ=ӂmSEFy+lǹHVċfN.E$Y͑^LX8SViO/c+cw~G(~~Oȥ}8-6EA\d7B6NqnEEDDD +[oosDDDDDDD.!"""""""v)ߊeLrwTZ ~m ڸN1,zL4IYѩ36gTu̽}w>a9#',9f+.\9gjqR5j)B؉?OY6DDDDD |+zϮcuu8%gՌ~Gεcp~h<1\; K⸱wO\btycޢk=S 4bR&vI6cث)圍~^o]דNAt}uF~Q\de!g9Ra~ya3*ʕz՟dvI\xc9JDDDDɷ?#xx}kU}(͉0M\ԁg?{6pX=Ѿ松zuĥ0s vV’BqM[)G8X)k)lmzaDm?`򻗊.s|Rc~ K9sVkǛo>G*c.pYX̀hxXG/|6q|W\Y:ҟ&[qG)Ӎ\\z M\ϰ.%ط;t7v*C3?gY^;wp$gt}6`Y)o`B5MDDDDR02i}yfh/+ٜw'羐 |1iߟ*KCTj3\>?wR II$O3h>71=*s-:]hY=WqkּA?jr%}Xo^Isl _;K閃y_ 2xTEۙSoJ8ņsn;£}T4pdoصVrq.*P\boXo$ '{L5믒X2[13s-Lo3hٗ~ }#}J'imZ;͆;Hu#Bv;J>͈_^.O$RCV.@ԫ>7ܩPULk<69"/rGOәy4<عd Ӎ_ʗqMpT  !""""RmJ5oN=#,:UA. 6I'e%nɣXDҰs<3+0s⧩|ڃ3| ~ ܹa! OSy,JвsJlcꎘq?}%oӈx]9b)YFޮ/n?#gx}:GC*ntko~ `8UKO6勥lZj9qzT|?/ pߞH{]9[qaKnEUVA7hsbC[?I2:g\ovV!vc\P/@nDDDDD$L#Kx9?$le̷&`%Wd>r2xfͪo- :ñ곴{?pM)1خ`~8G_#fO)"HrxnxzNDlk1ܺ2yMa<۬'m$;|1+owvPJe΀o9ۖpR4%(nG#j$o~?[͆k4Y S`T{)g>΃Y}dyr~B2/ҏ mlo6ď(rIDATc|/B!tWLX9<q<\w1ʔtȅ}8vi)+ѣ9ӹm^'h?7YLPNrfKn]ܑ?7G3h#puCnetΰ]ލ+ e2xPZ8w5T(zX ھ]_Į*y-ۼA/iCEjݓ߮xG2z)#a8k҇H9?g-`(ۖg+Ιup|{M;9ܥ]Hx>l!e{]/cq.u:t14#7Ŝv5_[OjoF3ļVߦ< __ȍv$V'<}kR!Nf_GS5"XTGr :Oy[>Adt/lj0M1Ƀ(wNk;+A[ƿ:H̪C$dxb~፩;waƟg|\Zf&cc{3>i[>gYZo/ر̠U2Ojj7i y5.0Y=Jcy +EDDDD\C`L Lz.17t`87Җ> %'L1ïgغ4]o$=i|sj8:g"W>#蜑1ib/5@Y{F9 m>^yM`//<;"""""R$NŊ :B- 0mZ_yMV UTȊ@BCCɓ!"""""^TTnnn8;;QjLP^mռDddd~WdWr3>L)qrr*0 ggg._zkd%Fɉ<ٷzADDDDD =łVC)lz5Yɫ92 y%=DDDDDDD.!"""""""vIEKzH.a 5˄7X21ƙ r@4#B"""""rg&u"/^pp/'qa|5']!szbZvkJa^" D$b8%ezȲ$]&:"А`CB &> v=}DDDDDDҞOE}7Z$r;ggCrΒSnӆGR \Ǭ :͚lBw\Crc zQ*=DDDDDb¶fW$%F}uW1d؏?Q/-S/'+IqDƓlq䊇FD\t4IXL+Nq 11'$b5Z /O7L KB F܋yj,ڹTCDDDDD Vg0l]b hч_dxxj$^lZnD\<DZ`gHt,N_\\c>N1Sw2]pcL[8cr`Nʼn#I&~?O`1cf|Gƽs5df(=T;ZՄ&:P iY1;܉2K`Ҁ ,Q19J8cD8Ue. xޓ~%*cDDo5U;3CvP<9st3qo1p>z}W/y^=cM,@I1O4ppu ar)MUiգ C<ɋ}!89UwmWx49s{rcg1v,'cLd%8G Rpzq!1* IշfB#c+{h&Os͗2lZ7ȺsY^iNeNFDa0\~odbտ%|ȳl(߫,G14EzwjDWnH"6"\3tmOaX^j5'1 x5)a3k _lt"9S?p㍾5|r;ntlA?/9b &ôy5%̟9JzMcp}֑VvNMCy~"kZ&w~}-'s~VN\KsʦS*T(SLFDDDDD$--k?o6fu'"fAAAΝ;RB"""""""bT%=DDDDDDD.!"""""""vIEKƂ@DDDDD$3ٌmmaXlʕ5Yɫyz$''tEFrr2nnnfMV򚒒[*zHE|| AntiMicroX profile file Plik z profilem AntimMicroX AntiMicroX-antimicrox-b300273/other/io.github.antimicrox.antimicrox.yml000066400000000000000000000011561471077622000262410ustar00rootroot00000000000000# Maintained on Flathub at https://github.com/flathub/io.github.antimicrox.antimicrox app-id: io.github.antimicrox.antimicrox runtime: org.kde.Platform runtime-version: '5.11' sdk: org.kde.Sdk command: antimicrox finish-args: # X11 + XShm access - --share=ipc - --socket=x11 # Gamepads - --device=all modules: - name: antimicrox buildsystem: cmake sources: - type: git url: https://github.com/AntiMicroX/antimicrox.git # Build top commit of master branch branch: master # You can also set a tag and/or commit to build # tag: 3.xx # commit: xxx AntiMicroX-antimicrox-b300273/share/000077500000000000000000000000001471077622000172545ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/LICENSE_SDL_GameControllerDB000066400000000000000000000016141471077622000241700ustar00rootroot00000000000000Simple DirectMedia Layer Copyright (C) 1997-2020 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. AntiMicroX-antimicrox-b300273/share/antimicrox/000077500000000000000000000000001471077622000214315ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/antimicrox/translations/000077500000000000000000000000001471077622000241525ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/antimicrox/translations/CMakeLists.txt000066400000000000000000000031141471077622000267110ustar00rootroot00000000000000# This will ensure that the *.qm files will be stored # in the right place within the build directory. file(GLOB antimicrox_TRANSLATIONS antimicrox_*.ts) list(APPEND antimicrox_TRANSLATIONS antimicrox.ts) file(GLOB_RECURSE antimicrox_BASE_SOURCES ${PROJECT_SOURCE_DIR}/src/*.cpp) file(GLOB_RECURSE antimicrox_BASE_FORMS ${PROJECT_SOURCE_DIR}/src/*.ui) if(QT_VERSION VERSION_GREATER_EQUAL 5.15) if(UPDATE_TRANSLATIONS) message("Update translations - lupdate ON") if(TRANS_REMOVE_OBSOLETE) message("getting rid of old text entries: \"lupdate -noobsolete\" ON") QT_CREATE_TRANSLATION(antimicrox_QMFILES ${antimicrox_BASE_SOURCES} ${antimicrox_BASE_FORMS} ${antimicrox_TRANSLATIONS} OPTIONS -no-obsolete) else() QT_CREATE_TRANSLATION(antimicrox_QMFILES ${antimicrox_BASE_SOURCES} ${antimicrox_BASE_FORMS} ${antimicrox_TRANSLATIONS}) endif(TRANS_REMOVE_OBSOLETE) else() QT_ADD_TRANSLATION(antimicrox_QMFILES ${antimicrox_TRANSLATIONS}) endif(UPDATE_TRANSLATIONS) else() # Since 5.15 QT commands are universal QT5_ADD_TRANSLATION(antimicrox_QMFILES ${antimicrox_TRANSLATIONS}) if(UPDATE_TRANSLATIONS) warning("Updating translations only for QT 5.15 or newer.") endif() endif() add_custom_target(updateqm DEPENDS ${antimicrox_QMFILES} COMMENT "Update translation files based on source and ui files") install(FILES ${antimicrox_QMFILES} DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/antimicrox/translations") set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM true) AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox.ts000066400000000000000000013212301471077622000267010ustar00rootroot00000000000000 AboutDialog About About Version Version Info Info Changelog Changelog Credits Credits AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development About Development "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Copyright: 2013 - 2022 {2013 ?} License License Program Version %1 Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Program Compiled on %1 at %2 Built Against SDL %1 Built Against SDL %1 Running With SDL %1 Running With SDL %1 Using Qt %1 Using Qt %1 Using Event Handler: %1 Using Event Handler: %1 AddEditAutoProfileDialog Auto Profile Dialog Auto Profile Dialog Pro&file: Pro&file: Browse Browse Window: Window: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Select Window. Click on the appropriate application window and the application file path will be populated in the form. Detect Window Properties Detect Window Properties &Class: &Class: T&itle: T&itle: set partial title set partial title Application: Application: Select Select De&vices: De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Set as Default for Controller Set as Default for Controller A different profile is already selected as the default for this device. A different profile is already selected as the default for this device. Current (%1) Current (%1) Open Config Open Config Select Program Select Program Programs (*.exe) Programs (*.exe) Please use the main default profile selection. Please use the main default profile selection. Main Profile Main Profile Already selected Already selected Chosen Profile Chosen Profile The selection will be used instead of the all default profile option. The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. Please select a window by using the mouse. Press Escape if you want to cancel. Capture Application Window Capture Application Window Could not obtain information for the selected window. Could not obtain information for the selected window. Application Capture Failed Application Capture Failed Profile file path is invalid. Profile file path is invalid. No window matching property was specified. No window matching property was specified. Program path is invalid or not executable. Program path is invalid or not executable. File is not an .exe file. File is not an .exe file. No window matching property was selected. No window matching property was selected. AdvanceButtonDialog Advanced Advanced Assignments Assignments Toggle Toggle Turbo Turbo Set Selector Set Selector Blank or KB/M Blank or KB/M Hold Hold Pause Pause Cycle Cycle Distance Distance Insert Insert Delete Delete Clear All Clear All Time: Time: 0.01s 0.01s 0s 0s Insert a pause that occurs in between key presses. Insert a pause that occurs in between key presses. Release Release Insert a new blank slot. Insert a new blank slot. Delete a slot. Delete a slot. Clear all currently assigned slots. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. Specify the duration of an inserted Pause or Hold slot. 0m 0m &Mouse Speed Mod: &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: Distance: % % Mouse Mod Mouse Mod Press Time Press Time Delay Delay Execute Execute Load Load Set Change Set Change Text Entry Text Entry Join Join Split Split Placeholder Placeholder 0 0 Set the percentage that mouse speeds will be modified by. Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After Auto Reset Cycle After seconds seconds Executable: Executable: ... ... Arguments: Arguments: Enabled Enabled Mode: Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Normal Gradient Gradient Pulse Pulse Delay: Delay: 0.10s 0.10s Rate: Rate: 10.0/s 10.0/s Disabled Disabled Select Set 1 One Way Select Set 1 One Way Select Set 1 Two Way Select Set 1 Two Way Select Set 1 While Held Select Set 1 While Held Select Set 2 One Way Select Set 2 One Way Select Set 2 Two Way Select Set 2 Two Way Select Set 2 While Held Select Set 2 While Held Select Set 3 One Way Select Set 3 One Way Select Set 3 Two Way Select Set 3 Two Way Select Set 3 While Held Select Set 3 While Held Select Set 4 One Way Select Set 4 One Way Select Set 4 Two Way Select Set 4 Two Way Select Set 4 While Held Select Set 4 While Held Select Set 5 One Way Select Set 5 One Way Select Set 5 Two Way Select Set 5 Two Way Select Set 5 While Held Select Set 5 While Held Select Set 6 One Way Select Set 6 One Way Select Set 6 Two Way Select Set 6 Two Way Select Set 6 While Held Select Set 6 While Held Select Set 7 One Way Select Set 7 One Way Select Set 7 Two Way Select Set 7 Two Way Select Set 7 While Held Select Set 7 While Held Select Set 8 One Way Select Set 8 One Way Select Set 8 Two Way Select Set 8 Two Way Select Set 8 While Held Select Set 8 While Held [NO KEY] [NO KEY] sec. sec. /sec. /sec. Not checked slots Not checked slots To delete slots, you need to select at least one To delete slots, you need to select at least one To insert slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Unknown current slot Click on chosen slots before joining them Click on chosen slots before joining them Not enough slots Not enough slots It's impossible to join slots. Add at least one other slot. It's impossible to join slots. Add at least one other slot. Not selected slots Not selected slots It's impossible to join slots. Select at least two slots before joining them It's impossible to join slots. Select at least two slots before joining them Only keyboard slots Only keyboard slots It's only possible to join simple and mix keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. It's impossible to split slots. Add at least one other slot. Not selected slot Not selected slot Select your slot before splitting. Select your slot before splitting. Too many mix slots Too many mix slots Select one mix slot. Select one mix slot. Only mix slots Only mix slots It's only possible to split mix slot. It's only possible to split mix slot. Empty execution path Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist File doesn't exist There is no such file locally, that could be executed. Check the file on your system There is no such file locally, that could be executed. Check the file on your system Set %1 Set %1 Select Set %1 Select Set %1 One Way One Way Two Way Two Way While Held While Held Choose Executable Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Choose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Execute program when slot is activated. Choose Profile Choose Profile Config Files (*.amgp *.xml) Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Stick/Pad Assignment Sticks Sticks DPads DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) %1 (Joystick %2) Stick 1 Stick 1 Enabled Enabled Assign Assign X Axis: X Axis: Y Axis: Y Axis: Stick 2 Stick 2 Number of Physical DPads: %1 Number of Physical DPads: %1 Virtual DPad 1 Virtual DPad 1 Up: Up: Down: Down: Left: Left: Right: Right: Axis %1 Axis %1 Axis %1 - Axis %1 - Axis %1 + Axis %1 + Button %1 Button %1 Move stick 1 along the X axis Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the X axis Move stick 2 along the Y axis Move stick 2 along the Y axis Press a button or move an axis Press a button or move an axis AxisEditDialog Axis Axis Mouse (Horizontal) Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Vertical) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Up | Down Arrows: Left | Right Arrows: Left | Right Keys: W | S Keys: W | S Keys: A | D Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 NumPad: KP_4 | KP_6 None None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Negative Half Throttle Positive Half Throttle Positive Half Throttle Haptic Trigger: Name: Name: Specify the name of an axis. Specify the name of an axis. Mouse Settings Mouse Settings Set the value of the dead zone for an axis. Set the value of the dead zone for an axis. Presets: Presets: Dead Zone: Dead Zone: Max Zone: Max Zone: [NO KEY] [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Negative Throttle Normal Normal Positive Throttle Positive Throttle Current Value: Current Value: Set Set Set %1 Set %1 Left Mouse Button Left Mouse Button Right Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Placeholder Toggle Toggle Enables a key press or release to only occur when a controller button is pressed. Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Enables rapid key presses and releases. Turbo controller. Turbo Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Attach the numeric keypad Last keyboard/mouse button: Last keyboard/mouse button: Slots Slots Na&me: Na&me: Specify the name of a button. Specify the name of a button. Action: Action: Specify the action that will be performed in game while this button is being used. Specify the action that will be performed in game while this button is being used. Advanced Advanced Choose your keyboard key Choose your keyboard key No button No button Last button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice No choice Before you open window with advanced settings, you have to choice a key Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set As last gamepad button has been set Index %1 Index %1 Calibration Form Form Input to calibrate: Steps Z TextLabel TextLabel X X gain offset Y Y Start calibration Start calibration Close Reset settings Reset settings Save Save Calibration Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Captured Window Properties Information About Window Information About Window Class: Class: TextLabel TextLabel Title: Title: Path: Path: Match By Properties Match By Properties Class Class Title Title Path Path Full Path Full Path File Name File Name DPadContextMenu Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad None None Standard Standard Eight Way Eight Way 4 Way Cardinal 4 Way Cardinal 4 Way Diagonal 4 Way Diagonal Mouse Settings Mouse Settings DPadEditDialog Dialog Dialog Presets: Presets: Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad None None Dpad Mode: Dpad Mode: &Name: &Name: 4 Way Cardinal 4 Way Cardinal 4 Way Diagonal 4 Way Diagonal DPad Delay: DPad Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Specify the name of a dpad. Specify the name of a dpad. Mouse Settings Mouse Settings Standard Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Eight Way Set Set Set %1 Set %1 EditAllDefaultAutoProfileDialog Default Profile Default Profile Profile: Profile: Browse Browse Open Config Open Config Profile file path is invalid. Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Extra Profile Settings Key Press Time: Key Press Time: 0.00 ms 0.00 ms Profile Name: Profile Name: s s GameController Game Controller Game Controller GameControllerDPad DPad DPad GameControllerMappingDialog Game Controller Mapping Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A A B B X X Y Y Back Back Start Start Guide Guide Left Shoulder Left Shoulder Right Shoulder Right Shoulder Left Stick Click Left Stick Click Right Stick Click Right Stick Click Left Stick X Left Stick X Left Stick Y Left Stick Y Right Stick X Right Stick X Right Stick Y Right Stick Y Left Trigger Left Trigger Right Trigger Right Trigger DPad Up DPad Up DPad Left DPad Left DPad Down DPad Down DPad Right DPad Right Mapping Mapping SDL 2 Game Controller Mapping String SDL 2 Game Controller Mapping String Last Axis Event: Last Axis Event: Current Axis Detection Dead Zone: Current Axis Detection Dead Zone: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Back Guide Guide Start Start LS Click LS Click RS Click RS Click L Shoulder L Shoulder R Shoulder R Shoulder L Trigger L Trigger R Trigger R Trigger GameControllerTrigger Trigger Trigger JoyAccelerometerButton Up Up Down Down Left Left Right Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis Axis JoyAxisButton Negative Negative Positive Positive Unknown Unknown Button Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Vertical) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Up | Down Arrows: Left | Right Arrows: Left | Right Keys: W | S Keys: W | S Keys: A | D Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 NumPad: KP_4 | KP_6 None None Mouse Settings Mouse Settings Left Mouse Button Left Mouse Button Right Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Distance change for button #%1 - %2 Button Button [NO KEY] [NO KEY] [Set %1 1W] [Set %1 1W] [Set %1 2W] [Set %1 2W] [Set %1 WH] [Set %1 WH] JoyButtonContextMenu Toggle Toggle Turbo Turbo Clear Clear Set Select Set Select Disabled Disabled Set %1 Set %1 Set %1 1W Set %1 1W Set %1 2W Set %1 2W Set %1 WH Set %1 WH JoyButtonSlot Mouse Mouse Up Up Down Down Left Left Right Right LB LB MB MB RB RB Pause Pause Hold Hold Cycle Cycle Distance Distance Release Release Mouse Mod Mouse Mod Press Time Press Time Delay Delay Load %1 Load %1 Set Change %1 Set Change %1 [Text] %1 [Text] %1 [Exec] %1 [Exec] %1 [NO KEY] [NO KEY] JoyControlStick Stick Stick JoyControlStickButton Up Up Down Down Left Left Right Right Button Button JoyControlStickContextMenu Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad None None Standard Standard Eight Way Eight Way 4 Way Cardinal 4 Way Cardinal 4 Way Diagonal 4 Way Diagonal Mouse Settings Mouse Settings JoyControlStickEditDialog Dialog Dialog X: X: 0 0 Y: Y: Distance: Distance: Presets: Presets: Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad None None Stick Mode: Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Cardinal 4 Way Diagonal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. The area (in degrees) that each diagonal region occupies. Square Stick: Square Stick: Percentage to modify a square stick coordinates to confine values to a circle Percentage to modify a square stick coordinates to confine values to a circle % % Stick Delay: Stick Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Modifier: Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Na&me: Specify the name of an analog stick. Specify the name of an analog stick. Mouse Settings Mouse Settings Standard Standard Bearing: Bearing: % Safe Zone: % Safe Zone: Eight Way Eight Way Dead Zone: Dead Zone: Max Zone: Max Zone: Diagonal Range: Diagonal Range: Set Set Set %1 Set %1 JoyControlStickModifierButton Modifier Modifier JoyDPad DPad DPad JoyDPadButton Up Up Down Down Left Left Right Right Button Button JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Button JoySensorContextMenu Mouse Settings Mouse Settings JoySensorEditDialog Dialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Safe Zone: Presets: Presets: Dead Zone: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: Diagonal Range: The area (in degrees) that each diagonal region occupies. The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Na&me: Na&me: Specify the name of an analog sensor. Mouse Settings Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None None Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad JoyTabWidget <New> <New> Battery level of controller Remove Remove Remove configuration from recent list. Remove configuration from recent list. Load Load Load configuration file. Load configuration file. Save Save Save changes to configuration file. Save changes to configuration file. Save As Save As Save changes to a new configuration file. Save changes to a new configuration file. Sets Sets Copy from Set Copy from Set Settings Settings Set 1 Set 1 Set 2 Set 2 Set 3 Set 3 Set 4 Set 4 Set 5 Set 5 Set 6 Set 6 Set 7 Set 7 Set 8 Set 8 Stick/Pad Assign Stick/Pad Assign Controller Mapping Controller Mapping Quick Set Quick Set Names Names Toggle button name displaying. Toggle button name displaying. Pref Pref Change global profile settings. Change global profile settings. Reset Reset Revert changes to the configuration. Reload configuration file. Revert changes to the configuration. Reload configuration file. Open Config Open Config Config Files (*.amgp *.xml) Config Files (*.amgp *.xml) Config File (*.%1.amgp) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Do you really want to reset buttons settings for joystick? Save Profile Changes? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sticks Sensors DPads DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1: %2 Set %1 Set %1 Copy Set Assignments Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Are you sure you want to copy the assignments and device properties from %1? Save Config Save Config Set Set Joystick Joystick Joystick JoystickStatusWindow Properties Properties Details Details Name: Name: %1 %1 Number: Number: Axes: Axes: Buttons: Buttons: Hats: Hats: Sensors: Battery: Battery: Unknown Unknown GUID: GUID: Game Controller: Game Controller: Axes Axes Buttons Buttons Hats Hats Sensors %1 (#%2) Properties %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None None Axis %1 Axis %1 Hat %1 Hat %1 No No Yes Yes MainSettingsDialog Edit Settings Edit Settings General General Controller Mappings Controller Mappings Language Language Auto Profile Auto Profile Mouse Mouse Advanced Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Close To Tray Have Windows start AntiMicroX at system startup. Have Windows start AntiMicroX at system startup. Launch At Windows Startup Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Only show the system tray icon when the program first launches. Launch in Tray Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Attach the numeric keypad Key Repeat Key Repeat Active keys will be repeatedly pressed when this option is enabled. Active keys will be repeatedly pressed when this option is enabled. Enable Enable Specifies how much time should elapse before key repeating begins. Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Português do Brasil Français Français Deutsch Deutsch Italiano Italiano 日本語 日本語 Русский Русский српски / srpski српски / srpski 简体中文 简体中文 Español Español українська українська Polski Polski History Si&ze: History Si&ze: Weight Modi&fier: Weight Modi&fier: Log File: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: Log Level: None None Error Error Warning Warning Info Info Verbose Debug Debug Note: To see the change of log level in console output (not in log file), application restart is required Note: To see the change of log level in console output (not in log file), application restart is required Reset Reset Class Class Pro&file Directory: Pro&file Directory: Show low battery notification Show empty battery notification Title Title Program Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Disable Enhance Pointer Precision Smoothing Smoothing Refresh Rate: Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Spring Screen: Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: Accel Numerator: 0 0 Accel Denominator: Accel Denominator: Accel Threshold: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Reset Acceleration Delay: Delay: ms ms Rate: Rate: times/s times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID GUID Mapping String Mapping String Disable? Disable? Delete Delete Default Default English English Active Active Devices: Devices: All All Device Device Profile Profile Default? Default? Add Add Edit Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Select Default Profile Directory Are you sure you want to delete the profile? Are you sure you want to delete the profile? Save Log File As Save Log File As Log Files (*.log) Log Files (*.log) Do you really want to reset setting? Do you really want to reset setting? Would you like to reset mappings too? Would you like to reset mappings too? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &App &Options &Options He&lp He&lp &Quit &Quit Ctrl+Q Ctrl+Q &Update Joysticks &Update Joysticks Ctrl+U Ctrl+U &Hide &Hide Ctrl+H Ctrl+H &About &About Ctrl+A Ctrl+A About &Qt About &Qt Ctrl+T Ctrl+T &Properties &Properties Ctrl+P Ctrl+P &Key Checker &Key Checker Ctrl+K Ctrl+K &GitHub Page &GitHub Page Ctrl+G Ctrl+G S&ettings S&ettings Ctrl+S Ctrl+S &Stick/Pad Assign &Stick/Pad Assign Ctrl+X Ctrl+X &Wiki &Wiki Ctrl+W Ctrl+W &Issues &Issues Ctrl+I Ctrl+I &Calibration &Calibration Ctrl+C Ctrl+C Home Page Home Page (%1) (%1) Open File Open File Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery %1 battery Battery level is less than %1 Battery level is less than %1 Device number: %1 Device name: %2 Device number: %1 Device name: %2 Update to %1 available Reading old profile Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore &Restore Calibration couldn't be opened Calibration couldn't be opened You must connect at least one controller to open the window You must connect at least one controller to open the window Run as Administrator? Run as Administrator? Failed to elevate program Failed to elevate program Failed to restart this program as the Administrator Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Mouse Settings - Set %1 Set %1 MouseButtonSettingsDialog Mouse Settings - Mouse Settings - Set %1 Set %1 MouseControlStickSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseDPadSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSensorSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSettingsDialog Mouse Settings Mouse Settings Mouse Mode: Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Cursor Spring Spring Acceleration: Acceleration: Enhanced Precision Enhanced Precision Linear Linear Quadratic Quadratic Cubic Cubic Quadratic Extreme Quadratic Extreme Power Function Power Function Easing Quadratic Easing Quadratic Easing Cubic Easing Cubic Mouse Speed Settings Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Enable to change the horizontal and vertical speed boxes at the same time. Change Together Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration Delta Acceleration &Multiplier: &Multiplier: Mi&n Threshold: Mi&n Threshold: 1 = 20 pps 1 = 20 pps Wheel Hori. Speed: Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: Easing Duration: s s Highest value to accelerate mouse movement by Highest value to accelerate mouse movement by x x Start %: Start %: Acceleration begins at this percentage of the base multiplier Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Minimum amount of axis travel required for acceleration to begin Max Threshold: Max Threshold: Maximum axis travel before acceleration has reached the multiplier value Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: E&xtra Duration: Curve: Curve: Ease Out Sine Ease Out Sine Ease Out Quad Ease Out Quad Ease Out Cubic Ease Out Cubic Release Radius: Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Relative Mouse Status Mouse Status X: X: 0 (0 pps) 0 (0 pps) Y: Y: 1 = 1 notch(es)/s 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: Hori&zontal Speed: &Vertical Speed: &Vertical Speed: Wheel Vert. Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Settings Spring Width: Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s %n notch/s %n notches/s QKeyDisplayDialog Key Checker Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Event Handler: Native Key Value: Native Key Value: 0x00000000 0x00000000 Qt Key Value: Qt Key Value: antimicro Key Value: AntiMicroX Key Value: QObject Super Super Menu Menu Mute Mute Vol+ Vol+ Vol- Vol- Play/Pause Play/Pause Play Play Pause Pause Prev Prev Next Next Mail Mail Home Home Media Media Search Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program Quitting Program # of joysticks found: %1 # of joysticks found: %1 List Joysticks: List Joysticks: --------------- --------------- Joystick %1: Joystick %1: Attempting to use fallback option %1 for event generation. Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Failed to open event generator. Exiting. Using %1 as the event generator. Using %1 as the event generator. Last button Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 is not an XML file. Profile location %1 does not exist. Profile location %1 does not exist. Controller identifier is not a valid value. Controller identifier is not a valid value. An invalid set number '%1' was specified. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. Controller identifier '%s'' is not a valid value. No set number was specified. No set number was specified. An invalid event generator was specified. An invalid event generator was specified. No event generator string was specified. No event generator string was specified. Unknown log level: No log file specified. No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 Quick Set %1 SetAxisThrottleDialog Throttle Change Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1: %2 Set %1 Set %1 SetNamesDialog Set Name Settings Set Name Settings Set 1 Set 1 Set 2 Set 2 Set 3 Set 3 Set 4 Set 4 Set 5 Set 5 Set 6 Set 6 Set 7 Set 7 Set 8 Set 8 Name Name SimpleKeyGrabberButton Mouse Mouse SpringModeRegionPreview Spring Mode Preview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 Using uinput device file %1 UInputHelper a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z Esc Esc F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace BackSpace Tab Tab [ [ ] ] \ \ CapsLock CapsLock ; ; ' ' Enter Enter Shift_L Shift_L , , . . / / Ctrl_L Ctrl_L Super_L Super_L Alt_L Alt_L Space Space Alt_R Alt_R Menu Menu Ctrl_R Ctrl_R Shift_R Shift_R Up Up Left Left Down Down Right Right PrtSc PrtSc Ins Ins Del Del Home Home End End PgUp PgUp PgDn PgDn NumLock NumLock * * + + KP_Enter KP_Enter KP_1 KP_1 KP_2 KP_2 KP_3 KP_3 KP_4 KP_4 KP_5 KP_5 KP_6 KP_6 KP_7 KP_7 KP_8 KP_8 KP_9 KP_9 KP_0 KP_0 SCLK SCLK Pause Pause Super_R Super_R Mute Mute VolDn VolDn VolUp VolUp Play Play Stop Stop Prev Prev Next Next [NO KEY] [NO KEY] UnixWindowInfoDialog Captured Window Properties Captured Window Properties Information About Window Information About Window Class: Class: TextLabel TextLabel Title: Title: Path: Path: Match By Properties Match By Properties Class Class Title Title Path Path VDPad VDPad VDPad VirtualKeyPushButton Space Space Tab Tab Shift (L) Shift (L) Shift (R) Shift (R) Ctrl (L) Ctrl (L) Ctrl (R) Ctrl (R) Alt (L) Alt (L) Alt (R) Alt (R) Alt Gr Alt Gr ` ` ~ ~ - - = = [ [ ] ] \ \ Caps Caps ; ; ' ' , , . . / / ESC ESC PRTSC PRTSC SCLK SCLK INS INS PGUP PGUP DEL DEL PGDN PGDN 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK NUM LK * * + + Enter Enter Del Del < < : : Super (L) Super (L) Menu Menu Up Up Down Down Left Left Right Right VirtualKeyboardMouseWidget Keyboard Keyboard Mouse Mouse Mouse Settings Mouse Settings Left Mouse Left Up Mouse Up Left Button Mouse Left Button Middle Button Mouse Middle Button Right Button Mouse Right Button Wheel Up Mouse Wheel Up Wheel Left Mouse Wheel Left Wheel Right Mouse Wheel Right Wheel Down Mouse Wheel Down Down Mouse Down Right Mouse Right Button 4 Mouse Button 4 Mouse 8 Mouse Mouse 8 Button 5 Mouse Button 5 Mouse 9 Mouse Mouse 9 NONE NONE [NO KEY] [NO KEY] Last button Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Others Applications Applications Browser Back Browser Back Browser Favorites Browser Favorites Browser Forward Browser Forward Browser Home Browser Home Browser Refresh Browser Refresh Browser Search Browser Search Browser Stop Browser Stop Calc Calc Email Email F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media Media Media Next Media Next Media Play Media Play Media Previous Media Previous Media Stop Media Stop Search Search Volume Down Volume Down Volume Mute Volume Mute Volume Up Volume Up VirtualMousePushButton INVALID INVALID WinAppProfileTimerDialog Capture Application Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Timer: Seconds Seconds Cancel Cancel WinExtras [NO KEY] [NO KEY] AntiMicro Profile X11Extras ESC ESC Tab Tab Space Space DEL DEL Return Return KP_Enter KP_Enter Backspace Backspace Alt Gr Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program in system tray only. Launch program with the tray menu disabled Launch program with the tray menu disabled Launch program without the main window displayed Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value value Unload currently enabled profile(s) Unload currently enabled profile(s) value(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID Start joysticks on a specific set. Value can be a controller index, name, or GUID number value number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type log-type Choose a file for logs writing Choose a file for logs writing filename filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_br.ts000066400000000000000000013044711471077622000273740ustar00rootroot00000000000000 AboutDialog About Version <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> Info <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> Changelog "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Credits AntiMicroX About Development License Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 AddEditAutoProfileDialog Auto Profile Dialog Browse Window: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Detect Window Properties Pro&file: &Class: T&itle: set partial title Application: Select De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Set as Default for Controller A different profile is already selected as the default for this device. Current (%1) Open Config Select Program Programs (*.exe) Please use the main default profile selection. Main Profile Already selected Chosen Profile The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. Capture Application Window Could not obtain information for the selected window. Application Capture Failed Profile file path is invalid. No window matching property was specified. Program path is invalid or not executable. File is not an .exe file. No window matching property was selected. AdvanceButtonDialog Advanced Assignments Toggle Turbo Set Selector Blank or KB/M Hold Pause Cycle Distance Insert Delete Clear All Time: 0.01s 0s Insert a pause that occurs in between key presses. Release Insert a new blank slot. Delete a slot. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. 0m &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: % Mouse Mod Press Time Delay Execute Load Set Change Text Entry Join Split Placeholder 0 Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After seconds Executable: ... Arguments: Enabled Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Delay: 0.10s Rate: 10.0/s Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] sec. /sec. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: Y Axis: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Down: Left: Right: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Haptic Trigger: Name: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Dead Zone: Max Zone: [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Last keyboard/mouse button: Slots Na&me: Specify the name of a button. Action: Specify the action that will be performed in game while this button is being used. Advanced Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel X gain offset Y Start calibration Close Reset settings Save Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAccelerometerButton Up Down Left Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Negative Positive Unknown Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Up Down Left Right LB MB RB Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] JoyControlStick Stick JoyControlStickButton Up Down Left Right Button JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: 0 Y: Distance: Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Down Left Right Button JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button JoySensorContextMenu Mouse Settings JoySensorEditDialog Dialog 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: Presets: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. s Na&me: Specify the name of an analog sensor. Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set %1 JoySensorPreset None Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad JoyTabWidget <New> Battery level of controller Remove Remove configuration from recent list. Load Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sensors DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Details Name: %1 Number: Axes: Buttons: Hats: Sensors: Battery: Unknown GUID: Game Controller: Axes Buttons Hats Sensors %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None Axis %1 Hat %1 No Yes MainSettingsDialog Edit Settings General Controller Mappings Language Auto Profile Mouse Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Show low battery notification Show empty battery notification Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: Pro&file Directory: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID Mapping String Disable? Delete Default English Active Devices: All Device Profile Default? Add Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Options He&lp &Quit Ctrl+Q &Update Joysticks Ctrl+U &Hide Ctrl+H &About Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page (%1) Open File Run as Administrator? Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. Failed to elevate program Failed to restart this program as the Administrator %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSensorSettingsDialog Mouse Settings Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s %n notch/s %n notches/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Super Menu Mute Vol+ Vol- Play/Pause Play Pause Prev Next Mail Home Media Search Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name SimpleKeyGrabberButton Mouse SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 2 3 4 5 6 7 8 9 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK * + Enter Del < : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard Mouse Mouse Settings Left Mouse Up Mouse Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel WinExtras [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_ca.ts000066400000000000000000015261101471077622000273500ustar00rootroot00000000000000 AboutDialog About Quant a Version Versió Info Informació Changelog Jornal de modificacions Credits Crèdits AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originàriament desenvolupat per Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Posteriorment mantingut pel grup AntiMicro a https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Seguidament per juliagoda a https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Ara per ara mantingut a https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contribuïdors: </span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Traductors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Portuguès Brasiler</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Xinès</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - Francès</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - Alemany</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - Alemany</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japonès</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Rus</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbi</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ucrainià</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Castellà</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italià</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polonès</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">LLICÈNCIA DE PÚBLIC GENERAL GNU</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Versió 3, 29 juny 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Tothom és permès a copiar i distribuir verbatim còpies d'aquest document de llicència, però no es permeten modificacions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preàmbul</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">La Llicència de Públic General GNU és una llicència lliure i "copyleft" per a programari i altres classes de feines. Les llicències per a la majoria de programari i altres obres pràctiques són dissenyades per treure la vostra llibertat de compartir i canviar les obres. Per contrast, la Llicència de Públic General GNU és pretesa per garantir la vostra llibertat de compartir i canviar totes les versions d'un programa--per assegurar queda programari lliure per tots els seus usuaris. Nosaltres, el Fonament de Programari Lliure, utilitzem la Llicència de Públic General GNU per la majoria de el nostre programari; aplica també a qualsevol altra obra publicada sota aquesta llicència pels seus autors. Hom pot aplicar-la als seus programes, també.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Quan parlem de programari lliure, estem referint a llibertat, no preu. Les nostres Llicències de Públic Generals són dissenyades per fer segur que tens la llibertat per distribuir còpies de programari lliure (i càrrec per a ells si desitges), que reps la font codificar o el pot rebre si el vols, que pots canviar el programari o utilitzar peces d'ell dins programes lliures nous, i que coneixes pots fer aquestes coses.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Per emparar els vostres drets, necessitem impedir altres des de negar-te aquests drets o preguntant-te per rendir-se els drets. Per això, tens responsabilitats segures si distribueixes còpies del programari, o si la modifiques: responsabilitats de respectar la llibertat d'altres.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Per exemple, si distribueixes còpies de tal programa, tant si gratis o per a un cost, has de passar damunt als destinataris les mateixes llibertats que et va rebre. Has de fer segur que elles, també, rep o pot rebre el codi de font. I #li has de mostrar aquests termes així que saben els seus drets.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Desenvolupadors aquell ús el GNU GPL empara els vostres drets amb dos passos:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) afirmar copyright en el programari, i (2) t'ofereix aquesta Llicència que et dona permís legal per copiar, distribueix i/o modificar-lo.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Per als desenvolupadors' i la protecció dels autors, el GPL clarament compta que no hi ha cap garantia per aquest programari lliure. Per a ambdós usuaris' i el bé dels autors, el GPL requereix que versions modificades ser marcat com canviat, de manera que els seus problemes no seran atribuïts erròniament a autors de versions anteriors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Alguns dispositius són dissenyats per negar accés d'usuaris per instal·lar o versions modificades corregudes del programari dins ells, tot i que el fabricant pot fer tan. Això és fonamentalment incompatible amb l'objectiu d'emparar la llibertat per canviar dels usuaris el programari. El patró sistemàtic de tal abús ocorre en l'àrea de productes per a individus per utilitzar, el qual és precisament on és més inacceptable. Per això, hem dissenyat aquesta versió del GPL per prohibir la pràctica per a aquells productes. Si tals problemes sorgeixen substancialment en altres àmbits, estem a punt per estendre aquesta provisió a aquells àmbits en el futur versions del GPL, com va necessitar emparar la llibertat d'usuaris.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A la fi, cada programa és aguaitat constantment per patents de programari. Els estats no haurien de permetre patents per restringir desenvolupament i utilitza de programari en ordinadors de propòsit general, però en els que fa, desitgem evitar el perill especial aquelles patents van aplicar a un programa lliure el podria fer eficaçment propietari. Per impedir això, el GPL assegura que no es poden soler les patents representar el programa no-lliure.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Els termes precisos i condicions per copiar, la distribució i la modificació segueixen.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMES I CONDICIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definicions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Aquesta Llicència&quot; refereix a versió 3 del GNU Llicència de Públic General.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; també significa copyright-com lleis que aplica a altres classes de feines, com màscares de semiconductor.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;El Programa&quot; refereix a qualsevol copyrightable la feina va llicenciar sota aquesta Llicència. Cadascú licensee és adreçat com &quot;et&quot;. &quot;Licensees&quot; i &quot;destinataris&quot; pot ser individus o organitzacions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;modifica&quot; uns mitjans de feina per copiar des d'o adapta tot o part de la feina de moda requerint permís de copyright, altre que el fer d'una còpia exacta. La feina resultant és anomenada un &quot;versió modificada&quot; de la feina més primerenca o una feina &quot;basat damunt&quot; la feina més primerenca.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Un &quot;feina coberta&quot; mitjans tampoc el unmodified Programa o una feina basada en el Programa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;propagar&quot; uns mitjans de feina per fer qualsevol cosa amb ella que, sense permís, et faria directament o secundàriament propens per a contravenció sota llei de copyright aplicable, excepte executant-la en un ordinador o modificant una còpia privada. La propagació inclou copiar, distribució (amb o sense modificació), fent disponible al públic, i en alguns països altres activitats també.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;transporta&quot; una feina significa qualsevol classe de propagació que habilita altres festes per fer o rebre còpies. Interacció mera amb un usuari a través d'una xarxa d'ordinador, amb cap trasllat d'una còpia, no està transportant.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Una interfície d'usuari interactiva mostra &quot;Anuncis Legals Apropiats&quot; a l'abast que l'inclou una característica convenient i prominentment visible allò (1) pantalles un anunci de copyright apropiat, i (2) diu l'usuari que no hi ha cap garantia per a la feina (exceptua a l'abast aquelles garanties són proporcionades), que licensees pot transportar la feina sota aquesta Llicència, i com per veure una còpia d'aquesta Llicència. Si la interfície presenta una llista d'ordres d'usuari o opcions, com un menú, un element prominent en la llista coneix aquest criteri.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Codi de font.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">El &quot;codi de font&quot; per a una feina significa la forma preferida de la feina per fer modificacions a ella. &quot;Codi d'objecte&quot; mitjans qualsevol no-forma de font d'una feina.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Un &quot;Interfície Estàndard&quot; significa una interfície que tampoc és un estàndard oficial definit per un ens d'estàndards homologat, o, en el cas de les interfícies especificades per un llenguatge de programació particular, u que és amplament utilitzat entre els desenvolupadors feiners en aquella llengua.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">El &quot;Biblioteques de Sistema&quot; d'una feina executable inclou qualsevol cosa, altre que la feina globalment, que (un) és inclòs en la forma normal d'empaquetar un Component Important, però quin no és part d'aquell Component Important, i (b) serveix només per habilitar ús de la feina amb aquell Component Important, o per implementar una Interfície Estàndard pel qual una implementació és disponible al públic en forma de codi de la font. Un &quot;Component Important&quot;, en aquest context, significa un component essencial important (nucli, sistema de finestra, etcètera) del sistema operatiu concret (si qualsevol) en el qual les curses de feina executables, o un compilador va soler produir la feina, o un intèrpret de codi de l'objecte va soler corregut el.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">El &quot;Font Corresponent&quot; per a una feina en forma de codi de l'objecte significa tot el codi de font va necessitar generar, instal·la, i (per una feina executable) corre el codi d'objecte i per modificar la feina, incloent guions per controlar aquelles activitats. Tanmateix, no inclou les biblioteques de Sistema de la feina, o eines de propòsit general o generalment programes lliures disponibles quins són utilitzats unmodified en actuar aquells les activitats però quin no són part de la feina. Per exemple, la font Corresponent inclou fitxers de definició de la interfície associats amb fitxers de font per a la feina, i el codi de font per biblioteques compartides i dinàmicament vinculat subprograms que la feina és concretament dissenyat per requerir, com per comunicació de dades íntimes o flux de control entre aquells subprograms i altres parts de la feina.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">La necessitat de Font Corresponent no inclou qualsevol cosa aquells usuaris poden regenerar automàticament des d'altres parts de la Font Corresponent.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">La Font Corresponent per a una feina en forma de codi de la font és que mateixa feina.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Permisos bàsics.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Tots drets van concedir sota aquesta Llicència és concedida per al terme de copyright en el Programa, i és irrevocable va proporcionar les condicions constades són conegudes. Aquesta Llicència explícitament afirma el vostre permís il·limitat per córrer el unmodified Programa. La sortida des de córrer una feina coberta és coberta per aquesta Llicència només si la sortida, donat el seu contingut, constitueix una feina coberta. Aquesta Llicència reconeix els vostres drets d'ús just o altre equivalent, com proporcionat per llei de copyright.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Pots fer, corre i propaga feines cobertes allò et no transporta, sense condicions tan llarg com la vostra llicència altrament queda en vigor. Pots transportar feines cobertes a altres pel propòsit únic de tenir fa modificacions exclusivament ja que et, o et proporciona amb facilitats per córrer aquells feines, amb la condició que obeeixes amb els termes d'aquesta Llicència en transportar tot material pel qual et no controla copyright. Aquells per això fent o corrent les feines cobertes ja que has de fer tan exclusivament damunt el vostre behalf, sota la vostra direcció i control, en termes allò #li prohibeix des de fer qualssevol còpies del vostre exterior material registrat la seva relació amb tu.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Transportar sota qualsevol altres circumstàncies és permesa només sota les condicions constades sota. Sublicensing no és permès; secció 10 la fa innecessari.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Emparant els drets Legals dels usuaris Des de Anti-Circumvention Llei.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Feina coberta no serà part considerada d'una mesura tecnològica eficaç sota qualsevol llei aplicable que compleix obligacions sota article 11 del WIPO tractat de copyright va adoptar el 20 de desembre de 1996, o les lleis similars que prohibeixen o restringint circumvention de tals mesures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Quan transportes una feina coberta, dispenses qualsevol poder legal de prohibir circumvention de mesures tecnològiques a l'abast tal circumvention és efectuat per exercitar drets sota aquesta Llicència amb respecte a la feina coberta, i tu disclaim qualsevol intenció per fitar operació o modificació de la feina com a mitjans d'aplicar, contra els usuaris de la feina, el vostre o els drets legals de terceres festes per prohibir circumvention de mesures tecnològiques.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Transportant Verbatim Còpies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Pots transportar verbatim còpies del codi de font del Programa mentre la reps, en qualsevol medi, amb la condició que tu visiblement i apropiadament publica en cada còpia un s'apropia anunci de copyright; segueix intacte tot els anuncis que consten que aquesta Llicència i qualsevol no-permissive els termes van afegir en acord amb secció 7 aplica al codi; segueix intacte tot nota de l'absència de qualsevol garantia; i dona tot destinataris una còpia d'aquesta Llicència juntament amb el Programa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Pots cobrar qualsevol preu o cap preu per a cada còpia que transportes, i pots oferir recolzar o protecció de garantia per a un cost.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Transportant Versions de Font Modificada.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Pots transportar una feina basada en el Programa, o les modificacions per produir-la des del Programa, en la forma de codi de font sota els termes de secció 4, amb la condició que també coneixes tot d'aquestes condicions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">un) La feina ha de portar els anuncis prominents que consten que te la va modificar, i donant una data pertinent.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) La feina ha de portar els anuncis prominents que consten que és soltada sota aquesta Llicència i qualssevol condicions van afegir sota secció 7. Aquest requisit modifica el requisit en secció 4 a &quot;seguir intacte tot nota&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Has de llicenciar la feina sencera, globalment, sota aquesta Llicència a algú que ve a possessió d'una còpia. Aquesta Llicència per això aplicarà, juntament amb qualsevol secció aplicable 7 termes addicionals, a la totalitat de la feina, i totes les seves parts, malgrat tot de com són empaquetades. Aquesta Llicència dona cap permís per llicenciar la feina en qualsevol altre camí, però no invalida tal permís si per separat l'has rebut.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Si la feina té interfícies d'usuari interactiu, cadascú ha de mostrar Anuncis Legals Apropiats; tanmateix, si el Programa té interfícies interactives allò no mostra Anuncis Legals Apropiats, la vostra necessitat de feina no els fa fa tan.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Una compilació d'una feina coberta amb altres feines separades i independents, els quals no són per les seves extensions de caràcter de la feina coberta, i quins no són combinats amb ella com per formar un programa més gran, dins o en un volum d'un emmagatzematge o medi de distribució, és anomenat un &quot;àrid&quot; si la compilació i el seu copyright resultant no són solguts fitar l'accés o drets legals dels usuaris de la compilació allèn de què el permís de feines individual. Inclusió d'una feina coberta en un àrid no causa aquesta Llicència per aplicar a les altres parts de l'àrid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Transportant No-Formes de Font.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Pots transportar una feina coberta en codi d'objecte forma sota els termes de seccions 4 i 5, amb la condició que també transportes la màquina-Font Corresponent llegible sota els termes d'aquesta Llicència, en un d'aquests camins:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">un) Transporta el codi d'objecte dins, o encarnat dins, un producte físic (incloent un medi de distribució físic), acompanyat per la Font Corresponent va fixar damunt un medi físic durador típicament utilitzat per a intercanvi de programari.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Transporta el codi d'objecte dins, o encarnat dins, un producte físic (incloent un medi de distribució físic), acompanyat per una oferta escrita, vàlid per com a mínim tres anys i vàlid per tan molt de temps mentre ofereixes client o parts sobreres suport per a aquell model de producte, per donar algú que posseeix el codi d'objecte qualsevol (1) una còpia de la Font Corresponent per tot el programari en el producte allò és #cobrir per aquesta Llicència, damunt un medi físic durador típicament utilitzat per a intercanvi de programari, per a un preu no més que el vostre cost raonable de físicament actuar aquest transportar de font, o (2) accés per copiar la Font Corresponent des d'un servidor de xarxa a cap càrrec.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Transporta còpies individuals del codi d'objecte amb una còpia de l'oferta escrita per proporcionar la Font Corresponent. Aquesta alternativa és permesa només ocasionalment i noncommercially, i només si vas rebre el codi d'objecte amb tal una oferta, en acord amb incís 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Transporta el codi d'objecte per oferir accés des d'un lloc designat (gratis o per a un càrrec), i ofereix accés equivalent a la Font Corresponent de la mateixa manera a través del mateix lloc a cap càrrec més llunyà. Necessites no requerir destinataris per copiar la Font Corresponent juntament amb el codi d'objecte. Si el lloc per copiar el codi d'objecte és un servidor de xarxa, la Font Corresponent pot ser en un servidor diferent (operat per tu o una tercera festa) aquell equivalent de suports que copia facilitats, va proporcionar mantens direccions clares després al codi d'objecte que diu on per trobar la Font Corresponent. Malgrat tot de quin servidor acull la Font Corresponent, quedes obligat per assegurar que és disponible per tan molt de temps com va necessitar satisfer aquests requisits.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Transporta el codi d'objecte que utilitza mirar atentament-a-mira atentament transmissió, va proporcionar informes altre mira atentament on el codi d'objecte i la font Corresponent de la feina està sent oferta al públic general a cap càrrec sota incís 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Una porció separable del codi d'objecte, la font de la qual el codi és exclòs des de la Font Corresponent com a Biblioteca de Sistema, necessitat no ser inclòs en transportar la feina de codi de l'objecte.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Un &quot;Producte d'Usuari&quot; és tampoc (1) un &quot;producte de consumidor&quot;, quins mitjans qualsevol propietat personal tangible quin és normalment utilitzat per personal, família, o propòsits de casa, o (2) qualsevol cosa dissenyat o venut per a incorporació a una vivenda. En determinar tant si un producte és un producte de consumidor, els casos dubtosos seran resolts a favor de cobertura. Per un producte particular va rebre per un usuari particular, &quot;normalment utilitzat&quot; refereix a un ús típic o comú d'aquella classe de producte, malgrat tot de l'estat de l'usuari particular o del camí en el qual l'usuari particular de fet utilitza, o espera o és esperat per utilitzar, el producte. Un producte és un producte de consumidor malgrat tot de tant si el producte té anunci sucós, industrial o no-usos de consumidor, llevat que tals usos representen el mode de significant únic d'ús del producte.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Informació d'instal·lació&quot; per a uns mitjans de Producte de l'Usuari qualssevol mètodes, procediments, claus d'autorització, o altra informació va requerir per instal·lar i executar versions modificades d'una feina coberta en aquell Producte d'Usuari des d'una versió modificada de la seva Font Corresponent. La informació ha de bastar per assegurar que el va continuar funcionar del codi d'objecte modificat és en cap cas impedit o interferit amb només perquè la modificació ha estat feta.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Si transportes una feina de codi de l'objecte sota aquesta secció dins, o amb, o concretament per a ús dins, un Producte d'Usuari, i el transportar ocorre com part d'una transacció en el qual el dret de la possessió i l'ús del Producte d'Usuari és transferit al destinatari a perpetuïtat o per un terme fix (malgrat tot de com la transacció és caracteritzada), la Font Corresponent va transportar sota s'ha d'acompanyar aquesta secció per la Informació d'Instal·lació. Però aquest requisit no aplica si ni et ni qualsevol tercera festa reté la capacitat d'instal·lar codi d'objecte modificat en el Producte d'Usuari (per exemple, la feina ha estat instal·lada en ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">El requisit per proporcionar Informació d'Instal·lació no inclou un requisit per continuar per proporcionar servei de suport, garantia, o actualitzacions per a una feina que ha estat modificat o instal·lat pel destinatari, o per al Producte d'Usuari en el qual ha estat modificat o instal·lat. L'accés a una xarxa pot ser negat quan la modificació ell mateix materialment i adversament afecta l'operació de la xarxa o viola les regles i protocols per a comunicació a través de la xarxa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">La font corresponent va transportar, i Informació d'Instal·lació va proporcionar, en l'acord amb aquesta secció ha de ser en un format allò és públicament documentat (i amb una implementació disponible al públic en forma de codi de la font), i ha de requerir cap contrasenya especial o clau per desempaquetar, llegint o copiar.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Termes addicionals.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Permisos addicionals&quot; és termes allò suplement els termes d'aquesta Llicència per fer excepcions des d'u o més de les seves condicions. Permisos addicionals que és aplicable al Programa sencer serà tractat tan encara que van ser inclosos en aquesta Llicència, a l'abast que són vàlids sota llei aplicable. Si els permisos addicionals apliquen només a part del Programa, es pot utilitzar aquella part per separat sota aquells permisos, però les restes de Programa senceres regides per aquesta Llicència sense consideració als permisos addicionals.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Quan transportes una còpia d'una feina coberta, pots a la vostra opció treure qualssevol permisos addicionals des d'aquella còpia, o des de qualsevol part d'ella. (es poden escriure els permisos addicionals per requerir el seu trasllat propi en casos segurs quan modifiques la feina.) Pots col·locar permisos addicionals en material, afegit per tu a una feina coberta, pel qual tens o pot donar apropiar-se permís de copyright.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding qualsevol altra provisió d'aquesta Llicència, per a material afegeixes a una feina coberta, pots (si autoritzat pels titulars de copyright d'aquell material) suplementa els termes d'aquesta Llicència amb termes:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">un) Disclaiming garantia o responsabilitat limitativa de forma diferent des dels termes de seccions 15 i 16 d'aquesta Llicència; o</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requerint preservació d'especificat anuncis legals raonables o escriure atribucions en aquell material o dins els Anuncis Legals Apropiats mostrats per les feines que la contenen; o</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibint misrepresentation de l'origen d'aquell material, o requerint que versions modificades de tal material ser marcat en camins raonables tan diferent des de la versió primigènia; o</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limitatiu l'ús per a propòsits de publicitat de noms de licensors o autors del material; o</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Decreixent de concedir drets sota llei de marca per a ús d'alguns noms comercials, marques, o marques de servei; o</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requerint indemnification de licensors i autors d'aquell material per algú que transporta el material (o va modificar versions d'ell) amb assumpcions contractuals de responsabilitat al destinatari, per a qualsevol responsabilitat que aquestes assumpcions contractuals directament imposen en aquells licensors i autors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Tot altre no-permissive els termes addicionals són considerats &quot;restriccions més llunyanes&quot; dins de l'accepció de secció 10. Si el Programa mentre el vas rebre, o qualsevol part d'ell, conté un anunci que consta que és regit per aquesta Llicència juntament amb un terme que és una restricció més llunyana, pots treure que terme. Si un document de llicència conté una restricció més llunyana però permisos relicensing o transportar sota aquesta Llicència, pots afegir a un material de feina cobert regit pels termes d'aquell document de llicència, amb la condició que la restricció més llunyana no sobreviu tal relicensing o transportar.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Si afegeixes termes a una feina coberta en acord amb aquesta secció, has de col·locar, en els fitxers de font pertinents, una declaració dels termes addicionals allò aplica a aquells fitxers, o un anunci que indica on per trobar els termes aplicables.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termes addicionals, permissive o no-permissive, pot ser constat en la forma d'una llicència per separat escrita, o constat com excepcions; el per sobre dels requisits apliquen qualsevol camí.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Venciment.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Et no pot propagar o modificar una feina coberta excepte tan expressament va proporcionar sota aquesta Llicència. Qualsevol intent altrament per propagar o modificar és nul, i automàticament rescindirà els vostres drets sota aquesta Llicència (incloent qualssevol llicències de patent van concedir sota el tercer paràgraf de secció 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Tanmateix, si cesses tota violació d'aquesta Llicència, llavors la vostra llicència des d'una titular de copyright particular és restablerta (un) provisionalment, llevat que i fins que el titular de copyright explícitament i a la fi rescindeix la vostra llicència, i (b) permanentment, si el titular de copyright falla per notificar-te de la violació per alguns mitjans raonables previs a 60 dies després del cessament.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A més, la vostra llicència des d'una titular de copyright particular és restablerta permanentment si el titular de copyright et notifica de la violació per alguns mitjans raonables, això és el primer cop t'ha rebut anunci de violació d'aquesta Llicència (per a qualsevol feina) des d'aquell titular de copyright, i cures la violació prèvia a 30 dies després del vostre rebut de l'anunci.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Venciment dels vostres drets sota aquesta secció no rescindeix les llicències de festes que ha rebut còpies o drets des de tu sota aquesta Llicència. Si els vostres drets han estat rescindits i no permanentment restablert, no capacites per rebre llicències noves pel mateix material sota secció 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. L'acceptació No Requerida per Tenir Còpies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Et no és requerit per acceptar aquesta Llicència en ordre de rebre o córrer una còpia del Programa. Propagació subsidiària d'una feina coberta que ocorre només a conseqüència d'utilitzar mira atentament-a-mira atentament transmissió per rebre una còpia així mateix no requereix acceptació. Tanmateix, res altre que aquesta Llicència et concedeix permís per propagar o modificar qualsevol feina coberta. Aquestes accions infringe copyright si no acceptes aquesta Llicència. Per això, per modificar o propagant una feina coberta, indiques la vostra acceptació d'aquesta Llicència per fer tan.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automàtic Llicenciar de Riu avall Destinataris.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Cada temps transportes una feina coberta, el destinatari automàticament rep una llicència des del primigeni licensors, per córrer, modifica i propaga que feina, subjecte a aquesta Llicència. No ets responsable per aplicar conformitat per terceres festes amb aquesta Llicència.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Un &quot;transacció d'entitat&quot; una transacció està transferint control d'una organització, o substancialment tots avantatges d'un, o subdividint una organització, o fusionant organitzacions. Si la propagació d'una feina coberta resulta des d'una transacció d'entitat, cada festa a aquella transacció que rep una còpia de la feina també rep qualsevol cosa llicencia a la feina el predecessor de la festa en l'interès va tenir o podria donar sota el paràgraf anterior, plus un dret a possessió de la Font Corresponent de la feina des del predecessor en interès, si el predecessor la té o la pot rebre amb esforços raonables.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Et no pot imposar cap restriccions més llunyanes en l'exercici dels drets va concedir o afirmat sota aquesta Llicència. Per exemple, no pots imposar un cost de llicència, reialesa, o altre càrrec per a l'exercici de drets va concedir sota aquesta Llicència, i no pots iniciar litigi (incloent una creu-reclamació o contradenúncia en una demanda) al·legant que qualsevol reclamació de patent és infringed per fer, utilitzant, venent, oferint en venda, o importador el Programa o qualsevol porció d'ella.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Un &quot;col·laborador&quot; és un titular de copyright que autoritza utilitzar sota aquesta Llicència del Programa o una feina en el qual el Programa és basat. La feina així va llicenciar és anomenat el col·laborador &quot;versió de col·laborador&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Un col·laborador &quot;reclamacions de patent essencial&quot; és tot patentar les reclamacions van posseir o controlat pel col·laborador, tant si ja adquirit o des d'ara adquirit, que seria infringed per alguna manera, permès per aquesta Llicència, de fer, utilitzant, o venent la seva versió de col·laborador, però no inclou reclamacions allò seria infringed només a conseqüència de modificació més llunyana de la versió de col·laborador. Per a propòsits d'aquesta definició, &quot;control&quot; inclou el dret de concedir patent sublicenses en una manera consistent amb els requisits d'aquesta Llicència.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Cada col·laborador et concedeix un no-exclusiu, mundialment, reialesa-llicència de patent lliure sota les reclamacions de patent essencial del col·laborador, per fer, ús, ven, oferta en venda, importació i altrament corregut, modifica i propaga els continguts de la seva versió de col·laborador.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">En el següent tres paràgrafs, un &quot;llicència de patent&quot; és qualsevol expressa acord o compromís, tanmateix denominat, no per aplicar una patent (com un expressa permís per practicar una patent o acord no per demandar per a contravenció de patent). A &quot;concedir&quot; tal llicència de patent a uns mitjans de festa per fer tal un acord o compromís no per aplicar una patent contra la festa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Si transportes una feina coberta, a gratcient confiar en una llicència de patent, i la Font Corresponent de la feina no és disponible per algú per copiar, de franc i sota els termes d'aquesta Llicència, a través d'una xarxa públicament disponible servidor o altres mitjans fàcilment accessibles, llavors has de tampoc (1) causa la Font Corresponent per ser tan disponible, o (2) arranjar per tu mateix privar del profit de la llicència de patent per aquesta feina particular, o (3) arranja, en una manera consistent amb els requisits d'aquesta Llicència, per estendre la llicència de patent a riu avall destinataris. &quot;A gratcient confiant&quot; significa tens saber real allò, però per a la llicència de patent, el vostre transportant la feina coberta en un país, o l'ús del vostre destinatari de la feina coberta en un país, infringe u o més patents identificables en aquell país que tens raó per creure és vàlida.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Si, pursuant a o en connexió amb una transacció sola o arranjament, transportes, o propagar per procurar conveyance de, una feina coberta, i concedeix una llicència de patent a alguns de les festes que reben la feina coberta que #li autoritza per utilitzar, propaga, modifica o transporta una còpia concreta de la feina coberta, llavors la llicència de patent concedeixes és automàticament estès a tot destinataris del cobert treballa i treballa basat en ell.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Una llicència de patent és &quot;discriminatori&quot; si no inclou dins de l'abast de la seva cobertura, prohibeix l'exercici de, o és condicionat damunt el no-exercici d'u o més dels drets allò és concretament concedit sota aquesta Llicència. No pots transportar una feina coberta si ets una festa a un arranjament amb una tercera festa que és en el negoci de distribuir programari, sota el qual fas pagament a la tercera festa basada en l'abast de la vostra activitat de transportar la feina, i sota el qual les terceres beques de festa, a qualsevol de les festes que rebria la feina coberta des de tu, una llicència de patent discriminatòria (un) en connexió amb còpies de la feina coberta transportada per tu (o les còpies van fer des d'aquelles còpies), o (b) principalment per i en connexió amb compilacions o productes concrets allò conté la feina coberta, llevat que vas entrar a aquell arranjament, o aquella llicència de patent va ser concedida, previ a 28 març 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Res en aquesta Llicència serà analitzat sintàcticament com excloure o limitatiu qualsevol va implicar llicència o altres defenses a contravenció allò altrament pot ser disponible a tu sota llei de patent aplicable.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. Cap Rendició d'Altres' Llibertat.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Si les condicions són imposades en tu (tant si per ordre de tall, acord o altrament) que contradiu les condicions d'aquesta Llicència, no et disculpen des de les condicions d'aquesta Llicència. Si no pots transportar una feina coberta a fi de satisfer simultàniament les vostres obligacions sota aquesta Llicència i qualsevol altres obligacions pertinents, llavors en conseqüència et no la pot transportar en absolut. Per exemple, si aparaules termes que t'obliga per recollir una reialesa per més llunyà transportar des d'aquells a qui transportes el Programa, el camí únic podries satisfer tant aquells els termes i aquesta Llicència serien per abstenir-se enterament des de transportar el Programa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Ús amb el GNU Affero Llicència de Públic General.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding qualsevol altra provisió d'aquesta Llicència, tens permís per vincular o combinar qualsevol feina coberta amb una feina va llicenciar sota versió 3 del GNU Affero Llicència de Públic General a una feina combinada sola, i per transportar la feina resultant. Els termes d'aquesta Llicència continuaran aplicar a la part quin és la feina coberta, però els requisits especials del GNU Affero Llicència de Públic General, secció 13, preocupant la interacció a través d'una xarxa aplicarà a la combinació com a tal.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Versions revisades d'aquesta Llicència.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">El Fonament de Programari Lliure pot publicar revisat i/o versions noves del GNU Llicència de Públic General ara i adés. Tals versions noves seran similars en esperit a la versió present, però pot diferir en detall per adreçar preocupacions o problemes nous.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Cada versió és #donar un distingint número de versió. Si el Programa especifica que un segur va numerar versió del GNU Llicència de Públic General &quot;o qualsevol versió més tardana&quot; aplica a ell, tens l'opció de següent els termes i condicions tampoc de que va numerar versió o de qualsevol versió més tardana publicada pel Fonament de Programari Lliure. Si el Programa no especifica un número de versió del GNU Llicència de Públic General, pots triar qualsevol versió mai publicada pel Fonament de Programari Lliure.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Si el Programa especifica que un proxy pot decidir quines versions futures del GNU es pot utilitzar Llicència de Públic General, la declaració pública d'aquell proxy d'acceptació d'una versió permanentment t'autoritza per triar que versió per al Programa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Versions de llicència més tardana et poden donar permisos addicionals o diferents. Tanmateix, cap obligació addicional és imposada en qualsevol autor o titular de copyright arran del vostre triar per seguir una versió més tardana.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer de Garantia.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">no hi ha CAP GARANTIA PER AL PROGRAMA, A L'ABAST va PERMETRE PER LLEI APLICABLE. EXCEPTE QUAN ALTRAMENT va CONSTAR PER ESCRIT ELS TITULARS de COPYRIGHT I/O ALTRES FESTES PROPORCIONEN EL PROGRAMA &quot;COM ÉS&quot; SENSE GARANTIA DE QUALSEVOL AMABLE, QUALSEVOL va EXPRESSAR O IMPLICAT, INCLOENT, PERÒ NO FITAT A, LES GARANTIES IMPLICADES DE MERCHANTABILITY I SALUT PER Un PROPÒSIT PARTICULAR. EL RISC SENCER COM A LA QUALITAT I l'actuació DEL PROGRAMA ÉS AMB tu. EL PROGRAMA PROVA DEFECTUÓS, SUPOSES EL COST DE TOT NECESSARI MANTENIR, REPARACIÓ O CORRECCIÓ.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitació de Responsabilitat.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">EN CAP SUCCÉS LLEVAT QUE REQUERIT PER LLEI APLICABLE O va APARAULAR PER ESCRIT QUALSEVOL REGISTRAR ELS DRETS D'AUTOR TITULAR, O QUALSEVOL ALTRA FESTA QUE MODIFICA I/O TRANSPORTA EL PROGRAMA COM PERMÈS DAMUNT, SIGUES PROPENS A TU PER A DANYS, INCLOENT QUALSEVOL GENERAL, ESPECIAL, DANYS INCIDENTALS O CONSEGÜENTS SORGIR FORA DE L'ÚS O INCAPACITAT per UTILITZAR EL PROGRAMA (INCLOENT EXCEPTE NO FITAT A PÈRDUA DE LA Dada O LA DADA que SÓN REPRESENTAT INEXACTE O les pèrdues van SOSTENIR PER Tu O TERCERES FESTES O Una FALLADA DEL PROGRAMA per OPERAR AMB QUALSEVOL ALTRES PROGRAMES), FINS I TOT SI TAL TITULAR O ALTRA FESTA HA ESTAT ACONSELLATS DE LA POSSIBILITAT DE TALS DANYS.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretació de Seccions 15 i 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Si el disclaimer de la garantia i la limitació de responsabilitat van proporcionar damunt no pot ser donat efecte legal local segons els seus termes, revisant els talls aplicaran llei local que més de prop aproxima un absolut waiver de tot responsabilitat civil en connexió amb el Programa, llevat que una garantia o l'assumpció de responsabilitat acompanya una còpia del Programa a canvi per a un cost.</span></p></body></html> About Development Quant al desenvolupament "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. "pktiuk" (des d'agost 2020) només vull assegurar, que aquesta peça mant útil del programari no serà abandonat, vaig decidir a continuar proporcionant recolzament per a aquest projecte i fer-lo tan amplament accessible com n'és possible. "juliagoda" (des de març, 2018 fins a 2020) Volent-ho només per jugar els meus jocs vells favorits que no admeten gamepads (comandaments de joc), vaig trobar aquest projecte (quines claus de teclat del mapa i botons de ratolí a connectat gamepads en Linux) tan més apropiat i recent. Però a causa d'eleccions pobres de tal aplicació en la internet i des de no va compilar pròpiament, vaig decidir rescatar el projecte. Tanmateix, una vegada que vaig acabar la meva feina (prou per gaudir jugar jocs) vaig pensar sobre la compartició aquest codi amb altres. Naturalment tota informació sobre programadors passats serà aguantada. "Ryochan7" (des de 30 de desembre de 2012 fins a 2017), he estat treballant damunt AntiMicro en el meu temps sobrer. Què al principi arrencat com a forca de QJoyPad i un camí d'aprendre succés apropiat-conduït programar s'ha convertit a alguna cosa molt més gran que al principi vaig voler pretendre. Tot i que he passat molt saber de temps tècniques noves, descobrint més sobre l'àmbit de KB+M emulació, i gastant nits de divendres donant'me de cops al cap contra el teclat, ha estat una divertida i enriquidora experiència en general. La necessitat per a aquest programa em va provenir utilitzant programes similars en Finestres per jugar diversos jocs que no va proporcionar suport de controlador natiu. Tot i que algunes alternatives van existir en Linux, no hi va haver molt qualsevol cosa que sentia era prou bo en termes de funcionalitat o dins-controls de joc en ordre a molt gaudir jocs allò vaig voler jugar amb utilitzar KB+M emulació. QJoyPad era el programa major que havia utilitzat antigament tot i que l'havia envellit molt i no va proporcionar alguna funcionalitat bàsica allò vaig pensar era essencial. El projecte era mort mentre no havia estat actualitzat en diversos anys així que vaig decidir fer el meu propi. Des de llavors, he intentat descobrir el que l'altre els programes fan drets i llavors millorar a ell. També he descobert alguns trucs polits pel camí i he après més aproximadament que natiu gamepad els controls són implementats en alguns jocs que jo mai molt volgut saber. Tot i que hi ha sens dubte àrees on aquest programa podria millorar, trobo que aquest programa ofereix el millor dins-experiència de control del joc per jugar més vell, i alguns més nou, jocs que no proporciona suport de controlador natiu. Desenvolupament d'aquest programa no és tan alt d'una prioritat per a mi anymore. Això és principalment a causa que el Controlador de Vapor treballa força bé per a la tasca de jugar jocs de PC comparats a utilitzar un controlador de Xbox 360. Tanmateix, sembla hi ha encara una raó per a aquest programa per existir durant una estona. --- Com de 24 demaig de 2016, aquest projecte ha mogut a https://github.com/AntiMicro/antimicro. A més, projectar la gerència ha passat des de Travis (Ryochan7) al AntiMicro organització a causa de Travis que té altres interessos i prioritats. Tan després, el projecte ha estat continuat des de 2018 per juliagoda damunt antimicroX projecte. El projecte més tardà ha estat altre cop va moure a https://github.com/AntiMicroX/antimicrox i és el seu manteniment és continuat per organització AntiMicroX creat per pktiuk. Copyright: 2013 - 2022 Copyright: 2013 - 2022 License Llicència Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 Fent servir el controlador d'events: %1 AddEditAutoProfileDialog Auto Profile Dialog Perfil automàtic de diàleg Pro&file: Per&fil: Browse Navega Window: Finestra: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Selecciona finestra. Clica la finestra de l'aplicació desitjada i la ruta del fitxer a l'aplicació serà generada automàticament al formulari. Detect Window Properties Detecta propietats de finestra &Class: &Classe: T&itle: T&ítol: set partial title metre títol parcial Application: Aplicació: Select De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Set as Default for Controller A different profile is already selected as the default for this device. Current (%1) Open Config Select Program Programs (*.exe) Please use the main default profile selection. Main Profile Already selected Chosen Profile The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. Capture Application Window Could not obtain information for the selected window. Application Capture Failed Profile file path is invalid. No window matching property was specified. Program path is invalid or not executable. File is not an .exe file. El fitxer no té format .exe. No window matching property was selected. No hi ha cap finestra amb la propietat seleccionada. AdvanceButtonDialog Advanced Avançat Assignments Tasques Toggle Turbo Set Selector Blank or KB/M Hold Pause Cycle Distance Insert Delete Clear All Time: 0.01s 0s Insert a pause that occurs in between key presses. Release Insert a new blank slot. Delete a slot. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. 0m &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: % Mouse Mod Press Time Delay Execute Load Set Change Text Entry Join Split Placeholder 0 Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After seconds Executable: ... Arguments: Enabled Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Delay: 0.10s Rate: 10.0/s Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] sec. /sec. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: Y Axis: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Down: Left: Right: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Haptic Trigger: Name: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Dead Zone: Max Zone: [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Attach the numeric keypad Last keyboard/mouse button: Slots Na&me: Specify the name of a button. Action: Specify the action that will be performed in game while this button is being used. Advanced Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel TextLabel X X gain offset Y Y Start calibration Close Reset settings Save Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAccelerometerButton Up Up Down Down Left Left Right Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Negative Positive Unknown Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Up Down Left Right LB MB RB Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] JoyControlStick Stick JoyControlStickButton Up Down Left Right Button JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: 0 Y: Distance: Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Down Left Right Button JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Button JoySensorContextMenu Mouse Settings Mouse Settings JoySensorEditDialog Dialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Safe Zone: Presets: Presets: Dead Zone: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: Diagonal Range: The area (in degrees) that each diagonal region occupies. The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Na&me: Na&me: Specify the name of an analog sensor. Mouse Settings Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None None Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad JoyTabWidget <New> Battery level of controller Remove Remove configuration from recent list. Load Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sensors DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Details Name: %1 Number: Axes: Buttons: Hats: Sensors: Battery: Unknown GUID: Game Controller: Axes Buttons Hats Sensors %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None None Axis %1 Hat %1 No Yes MainSettingsDialog Edit Settings General Controller Mappings Language Auto Profile Mouse Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Pro&file Directory: Show low battery notification Show empty battery notification Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID Mapping String Disable? Delete Default English Active Devices: All Device Profile Default? Add Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Options He&lp &Quit Ctrl+Q &Update Joysticks Ctrl+U &Hide Ctrl+H &About Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page (%1) Open File Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Failed to elevate program Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSensorSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Prev Next Mail Home Media Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name SimpleKeyGrabberButton Mouse SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 2 3 4 5 6 7 8 9 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK * + Enter Del < : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard Mouse Mouse Settings Left Mouse Up Mouse Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel WinExtras [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_de.ts000066400000000000000000013452331471077622000273620ustar00rootroot00000000000000 AboutDialog About Über Version Version <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> Info Info <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> Changelog Änderungsprotokoll "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. "pktiuk" (seit August 2020) Ich möchte sichergehen, dass diese nützliche Software nicht aufgegeben wird und habe mich entschlossen dieses Projekt weiter zu unterstützen und es so zugänglich wie möglich zu machen. "juliagoda" (seit März 2018 bis 2020) Da ich nur meine alten Lieblingsspiele spielen wollte, die keine Gamepads unterstützen, fand ich dieses Projekt (welches die Tastatur- und Maustasten auf verbundene Gamepads in Linux zuweist) als am besten geeignet und aktuellsten. Aber wegen der geringen Auswahl an solchen Anwendungen im Internet und weil es nicht richtig kompiliert wurde, habe ich beschlossen, das Projekt zu retten. Sobald ich jedoch meine Arbeit beendet hatte (genug, um das Spielen zu genießen), dachte ich darüber nach, diesen Code mit anderen zu teilen. Selbstverständlich werden alle Angaben über frühere Programmierer beihalten. "Ryochan7" (seit 30. Dezember 2012 bis 2017), ich habe in meiner Freizeit an AntiMicro gearbeitet. Was ursprünglich als Fork von QJoyPad und als Möglichkeit, die richtige ereignisgesteuerte Programmierung zu lernen, begann, hat sich zu etwas viel Größerem entwickelt, als ich ursprünglich vorhatte. Obwohl ich viel Zeit damit verbracht habe neue Techniken zu lernen, mehr über das Feld der KB+M-Emulation herauszufinden und Freitagabende damit zu verbringen, meinen Kopf auf die Tastatur zu hauen, war es insgesamt eine spaßige und bereichernde Erfahrung. Die Notwendigkeit für dieses Programm ergab sich daraus, dass ich ähnliche Programme unter Windows verwendete, um verschiedene Spiele zu spielen, die keine native Controller-Unterstützung boten. Obwohl es für Linux einige Alternativen gab, gab es nicht wirklich etwas, das meiner Meinung nach in Bezug auf die Funktionalität oder die Steuerung im Spiel gut genug war, um die Spiele, die ich mit der KB+M-Emulation spielen wollte, wirklich zu genießen. QJoyPad war das Programm, das ich in der Vergangenheit hauptsächlich verwendet hatte, obwohl es in die Jahre gekommen war und einige grundlegende Funktionen, die ich für wichtig hielt, nicht bieten konnte. Das Projekt war stillgelegt, da es seit mehreren Jahren nicht mehr aktualisiert worden war, und so beschloss ich, mein eigenes zu entwickeln. Seitdem habe ich versucht herauszufinden was die anderen Programme richtig machen und es dann zu verbessern. Dabei habe ich auch einige nützliche Tricks entdeckt und ich habe mehr darüber gelernt, wie die native Gamepad-Steuerung in einigen Spielen implementiert ist, als ich jemals wirklich wissen wollte. Obwohl es durchaus Bereiche gibt, in denen dieses Programm verbessert werden könnte, finde ich, dass dieses Programm das beste Steuerungserlebnis im Spiel bietet, um ältere und auch manche neuere Spiele zu spielen, die keine native Controller-Unterstützung bieten. Die Entwicklung dieses Programms hat für mich keine so hohe Priorität mehr. Das liegt vor allem daran, dass der Steam Controller für die Aufgabe, PC-Spiele zu spielen, im Vergleich zu einem Xbox 360-Controller ziemlich gut funktioniert. Es sieht jedoch so aus, als gäbe es für dieses Programm noch einen Grund für eine Weile zu bestehen. --- Seit dem 24. Mai 2016 ist dieses Projekt auf https://github.com/AntiMicro/antimicro umgezogen. Zusätzlich ist die Projektleitung von Travis (Ryochan7) an die AntiMicro Organisation übergegangen, da Travis andere Interessen und Prioritäten hat. Danach wurde das Projekt seit 2018 von juliagoda im antimicroX Projekt weitergeführt. Später wurde das Projekt noch einmal auf https://github.com/AntiMicroX/antimicrox verschoben und seine Instandhaltung wird von der von pktiuk gegründeten Organisation AntiMicroX fortgesetzt. Copyright: 2013 - 2022 Urheberrecht: 2013 - 2022 Credits Mitwirkende AntiMicroX About Development Über die Entwicklung License Lizenz Program Version %1 Programmversion %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Programm kompiliert am %1 um %2 Built Against SDL %1 Nutzt SDL %1 Running With SDL %1 Läuft mit SDL %1 Using Qt %1 Benutzt Qt %1 Using Event Handler: %1 Verwendung des Ereignisbehandlers: %1 AddEditAutoProfileDialog Auto Profile Dialog Auto-Profil-Dialog Pro&file: Pro&fil: Browse Durchsuchen Window: Fenster: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Wählen Sie das Fenster. Klicken Sie auf das entsprechende Anwendungs-Fenster und der Anwendungs-Dateipfad wird in das Formular eingetragen. Detect Window Properties Erkenne Fenstereigenschaften &Class: &Klasse: T&itle: T&itel: set partial title Teiltitel setzen Application: Anwendung: Select Wähle De&vices: Ge&räte: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Wählen Sie dieses Profil als Standard für das jeweilige Gerät. Diese Auswahl wird anstatt jeder anderen Standardeinstellung genutzt. Set as Default for Controller Setze als Standardcontroller A different profile is already selected as the default for this device. Ein anderes Profil ist bereits als Standard für dieses Gerät ausgewählt. Current (%1) Aktuell (%1) Open Config Konfiguration öffnen Select Program Wähle Anwendung Programs (*.exe) Programme (*.exe) Please use the main default profile selection. Bitte benutzen Sie die Standard-Profilauswahl. Main Profile Hauptprofil Already selected Bereits ausgewählt Chosen Profile Ausgewähltes Profil The selection will be used instead of the all default profile option. Die Auswahl wird statt der Option des Standardprofiles verwendet. Please select a window by using the mouse. Press Escape if you want to cancel. Bitte wählen Sie mit der Maus ein Fenster aus. Escape drücken um abzubrechen. Capture Application Window Anwendungsfenster auswählen Could not obtain information for the selected window. Konnte nicht Information für das ausgewählte Fenster gewinnen. Application Capture Failed Anwendungsauswahl fehlgeschlagen Profile file path is invalid. Profil-Dateipfad ist ungültig. No window matching property was specified. Kein zugehöriges Fenster wurde spezifiziert. Program path is invalid or not executable. Programmpfad ist ungültig oder nicht ausführbar. File is not an .exe file. Datei ist keine .exe-Datei. No window matching property was selected. Kein zugehöriges Fenster wurde ausgewählt. AdvanceButtonDialog Advanced Erweitert Assignments Zuweisungen Toggle Umschalten Turbo Turbo Set Selector Wähle Set Blank or KB/M Leer oder KB/M Hold Halten Pause Pause Cycle Kreislauf Distance Distanz Insert Einfügen Delete Entfernen Clear All Leeren Time: Zeit: 0.01s 0.01s 0s 0s Insert a pause that occurs in between key presses. Füg eine Pause zwischen den Tasten ein. Release Freigeben Insert a new blank slot. Füg eine neue leere Aktion hinzu. Join Verbinde Split Teile Delete a slot. Lösche eine Aktion. Clear all currently assigned slots. Lösche alle zugewiesenen Aktionen. Specify the duration of an inserted Pause or Hold slot. Gib die Dauer der hinzugefügten Pause- oder Haltenaktion an. 0m 0m &Mouse Speed Mod: &Mausgeschwindigkeitsmodus: Specify the range past an axis dead zone in which a sequence of actions will execute. Gib die Distanz der Achse zur "Dead Zone" an, in der die Sequenz an Aktionen ausgeführt wird. Distance: Distanz: % % Mouse Mod Maus Mod Press Time Druckzeit Delay Verzögerung Execute Ausführung Load Laden Set Change Gruppewahl Text Entry Texteintrag Placeholder Platzhalter 0 0 Set the percentage that mouse speeds will be modified by. Stelle den Prozentsatz ein um der die Mausgeschwindigkeit modifiziert werden soll. Auto Reset Cycle After Zyklus automatisch neustarten nach seconds Sekunden Executable: ausführbare Datei: ... ... Arguments: Argumente: Enabled Aktiviert Mode: Modus: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>Normal: Wiederholt mit der eingestellten Rate Taste drücken und loslassen.</p><p>Verlaufend: Ändere die Auslösen-/Loslassen-Verzögerung aufgrund wie weit die eine Achse bewegt wurde.</p><p>Pulsierend: Ändere wie häufig eine Taste pro Sekunde ausgelöst wurde. Die Verögerung bleibt gleich.</p></body></html> Normal Normal Gradient Verlaufend Pulse Pulsierend Delay: Verzögerung: 0.10s 0.10s Rate: Rate: 10.0/s 10.0/s Disabled Deaktiviert Select Set 1 One Way Wähle Gruppe 1: einseitig Select Set 1 Two Way Wähle Gruppe 1: wechselseitig Select Set 1 While Held Wähle Gruppe 1: festgehalten Select Set 2 One Way Wähle Gruppe 2: einseitig Select Set 2 Two Way Wähle Gruppe 2: wechselseitig Select Set 2 While Held Wähle Gruppe 2: festgehalten Select Set 3 One Way Wähle Gruppe 3: einseitig Select Set 3 Two Way Wähle Gruppe 3: wechselseitig Select Set 3 While Held Wähle Gruppe 3: festgehalten Select Set 4 One Way Wähle Gruppe 4: einseitig Select Set 4 Two Way Wähle Gruppe 4: wechselseitig Select Set 4 While Held Wähle Gruppe 4: festgehalten Select Set 5 One Way Wähle Gruppe 5: einseitig Select Set 5 Two Way Wähle Gruppe 5: wechselseitig Select Set 5 While Held Wähle Gruppe 5: festgehalten Select Set 6 One Way Wähle Gruppe 6: einseitig Select Set 6 Two Way Wähle Gruppe 6: wechselseitig Select Set 6 While Held Wähle Gruppe 6: festgehalten Select Set 7 One Way Wähle Gruppe 7: einseitig Select Set 7 Two Way Wähle Gruppe 7: wechselseitig Select Set 7 While Held Wähle Gruppe 7: festgehalten Select Set 8 One Way Wähle Gruppe 8: einseitig Select Set 8 Two Way Wähle Gruppe 8: wechselseitig Select Set 8 While Held Wähle Gruppe 8: festgehalten [NO KEY] [KEINE TASTE] sec. Sek. /sec. /Sek. Not checked slots Nicht überprüfte Slots To delete slots, you need to select at least one Um Slots zu löschen, musst du mindestens einen Slot auswählen To insert slots, you need to select at least one Um Slots einzufügen, musst du mindestens einen Slot auswählen Unknown current slot Unbekannter aktueller Slot Click on chosen slots before joining them Klicke auf die ausgewählten Slots, bevor du die schließst an Not enough slots Nicht genügend Slots It's impossible to join slots. Add at least one other slot. Es ist unmöglich, um Slots zu verbinden. Füge mindestens einen weiteren Slot hinzu. Not selected slots Nicht ausgewählte Slots It's impossible to join slots. Select at least two slots before joining them Es ist unmöglich, um Slots zu verbinden. Wähle mindestens zwei Slots bevor aus Only keyboard slots Nur Tastatur-Slots It's only possible to join simple and mix keyboard slots Es ist nur möglich, einfache und gemischte Tastatur-Slots zu verbinden It's impossible to split slots. Add at least one other slot. Es ist unmöglich, um Slots zu teilen. Füge mindestens einen weiteren Slot hinzu. Not selected slot Nicht ausgewählte Slots Select your slot before splitting. Wähle deinen Slot bevor aus. Too many mix slots Zu viele Mix-Slots Select one mix slot. Wähle einen Mix-slot aus. Only mix slots Nur Mix-Slots It's only possible to split mix slot. Es ist nur möglich, den Mix-Slot zu teilen. Empty execution path Leerer Ausführungspfad Line for execution file path is empty. Fill the first line before you are going to add a slot. Die Zeile für den Pfad der Ausführungsdatei ist leer. Fülle die erste Zeile, bevor Sie einen Slot hinzufügen. File doesn't exist Datei existiert nicht There is no such file locally, that could be executed. Check the file on your system Es gibt keine solche Datei lokal, die ausgeführt werden könnte. Überprüfe die Datei auf Ihrem System Set %1 Gruppe %1 Select Set %1 Wähle Gruppe %1 One Way Einweg Two Way Zweiwege While Held Solang wie gehalten Choose Executable Wähle ausführbare Datei Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Slots nach einer Zyklus-Aktion werden beim nächsten Tastendruck ausgeführt. Es können mehrere Zyklen hinzugefügt werden, um Partitionen in einer Sequenz zu erstellen. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Verzögert den Zeitpunkt der Aktivierung des nächsten Slots um die angegebene Zeit. Slots, die vor der Verzögerung aktiviert wurden, bleiben auch nach Ablauf der Verzögerungszeit aktiv. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Die Abstandsaktion legt fest, dass Slots anschließend nur dann ausgeführt werden, wenn eine Achse um einen bestimmten Bereich über die festgelegte Totzone hinaus bewegt wird. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Füge eine Halteaktion ein. Slots nach der Aktion werden nur ausgeführt, wenn die Taste über das angegebene Intervall hinaus gehalten wird. Chose a profile to load when this slot is activated. Wähle ein Profil zum Laden wenn dieser Slot aktiviert ist. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Die Maus-Mod-Aktion ändert alle Einstellungen der Mausgeschwindigkeit um einen bestimmten Prozentsatz, während die Aktion ausgeführt wird. Dies kann nützlich sein, um die Maus während des Scharfschneidens zu verlangsamen. Specify the time that keys past this slot should be held down. Gib die Zeit an, die die Tasten nach diesem Schlitz gedrückt gehalten werden sollen. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Füg eine Freigabe-Aktion ein. Slots nach der Aktion werden nach dem Loslassen einer Taste nur dann ausgeführt, wenn die Taste über das angegebene Intervall hinaus gehalten wurde. Change to selected set once slot is activated. Wechsle zu ausgewählter Gruppe wenn Slot aktiviert ist. Full string will be typed when a slot is activated. Die vollständige Zeichenfolge wird eingegeben, wenn ein Slot aktiviert wird. Execute program when slot is activated. Führe das Programm aus, wenn der Slot aktiviert ist. Choose Profile Wähle Profil Config Files (*.amgp *.xml) Konfigurationsdateien (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Stick/Pad Zuweisung Sticks Sticks DPads DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. Hinweis: Dieses Fenster dient der Rückwärtskompatibilität mit Profilen, die vor Antimicro 2.0 hergestellt wurden. Seit Version 2.0 wird die Verwendung des Game Controller Mapping-Fensters bevorzugt. %1 (Joystick %2) %1 (Joystick %2) Stick 1 Stick 1 Enabled Aktiviert Assign Zuweisen X Axis: X Achse: Y Axis: Y Achse: Stick 2 Stick 2 Number of Physical DPads: %1 Nummer der physischen DPads: %1 Virtual DPad 1 Virtueller DPad 1 Up: Hoch: Down: Runter: Left: Links: Right: Rechts: Axis %1 Achse %1 Axis %1 - Achse %1 - Axis %1 + Achse %1 + Button %1 Button %1 Move stick 1 along the X axis Bewege Stick 1 entlang der X Achse Move stick 1 along the Y axis Bewege Stick 1 entlang der Y Achse Move stick 2 along the X axis Bewege Stick 2 entlang der X Achse Move stick 2 along the Y axis Bewege Stick 2 entlang der Y Achse Press a button or move an axis Drücke einen Button oder bewege eine Achse AxisEditDialog Axis Achse Mouse (Horizontal) Maus (Horizontal) Mouse (Inverted Horizontal) Maus (Invertiert Horizontal) Mouse (Vertical) Maus (Vertikal) Mouse (Inverted Vertical) Maus (Invertiert Vertikal) Arrows: Up | Down Pfeiltasten: Hoch | Runter Arrows: Left | Right Pfeiltasten: Links | Rechts Keys: W | S Tasten: W | S Keys: A | D Tasten: A | D NumPad: KP_8 | KP_2 Nummernblock: KP_8 | KP_2 NumPad: KP_4 | KP_6 Nummernblock: KP_4 | KP_6 None Nichts Set the value to use as the limit for an axis. Useful for a worn out analog stick. Setze einen Wert als Limitierung einer Achse. Nützlich bei abgenutzten Analogsticks. Negative Half Throttle Negative Halbbeschleunigung Positive Half Throttle Positive Halbbeschleunigung Haptic Trigger: Haptischer Auslöser: Name: Name: Specify the name of an axis. Vergebe den Namen der Achse. Mouse Settings Mauseinstellungen Set the value of the dead zone for an axis. Bestimmt den Wert der Dead Zone einer Achse. Presets: Vorgaben: Dead Zone: Dead Zone: Max Zone: Max Zone: [NO KEY] [KEINE TASTE] Throttle setting that determines the behavior of how to interpret an axis hold or release. Beschleunigung gibt das Verhalten an wie das Halten oder Loslassen einer Achse interpretiert wird. Negative Throttle Negative Beschleunigung Normal Normal Positive Throttle Positive Beschleunigung Current Value: Aktueller Wert: Set Set Set %1 Set %1 Left Mouse Button Linke Maustaste Right Mouse Button Rechte Maustaste Click Klick Rigid Fest Rigid Gradient Festigkeitsverlauf Vibration Vibration ButtonEditDialog Dialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Um eine neue Zuweisung zu machen, drück eine Taste oder klick einen Button im Tastatur oder Mausreiter Placeholder Platzhalter Toggle Umschalten Enables a key press or release to only occur when a controller button is pressed. Tasten werden erst, wenn der Button gedrückt wurde entweder festgehalten oder frei gelassen. Enables rapid key presses and releases. Turbo controller. Aktiviert schnelles Tastendrücken oder Freigeben. Autofeuer. Turbo Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Denke daran, dass es nicht funktionieren wird, wenn du keine solche Tastatur an den Rechner angeschlossen hast oder wenn sie nicht integriert ist wie bei Desktop-PCs. Attach the numeric keypad Anschluss einer numerischen Tastatur Last keyboard/mouse button: Letzte Tastatur-/Maustaste: Slots Slots Na&me: Na&me: Specify the name of a button. Vergebe den Namen des Buttons. Action: Aktion: Specify the action that will be performed in game while this button is being used. Gibt die Aktion des Buttons an, die Ingame genutzt wird. Advanced Fortgeschrittene Choose your keyboard key Wähle deine Tastaturtaste No button Keine Taste Last button Letzte Taste To change settings for last button, it must be at least one assignment from keyboard to gamepad Um die Einstellungen für die letzte Taste zu ändern, muss es mindestens eine Zuordnung von der Tastatur zum Gamepad geben To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad Um die Einstellungen von Turbo für die letzte Taste zu ändern, muss es mindestens eine Zuordnung von Tastatur zu Gamepad geben No choice Keine Wahl Before you open window with advanced settings, you have to choice a key Bevor du ein Fenster mit den erweiterten Einstellungen öffnest, musst du einen Schlüssel wählen To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Um den erweiterten Dialog zu öffnen, muss mindestens eine Taste von der Tastatur auf das Gamepad gelegt werden Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Slots für die Tasten konnten nicht gelöscht werden, da es keine Taste für das Gamepad auf der Tastatur gab. Belege mindestens eine Taste von der Tastatur für das Gamepad As last gamepad button has been set Da die letzte Gamepad-Taste eingestellt wurde Index %1 Index %1 Calibration Form Formular Input to calibrate: Input zum Kalibrieren: Steps Schritte Z Z TextLabel TextEtikett X X gain Zuwachs offset Ausgleich Y Y Start calibration Starte Kalibrierung Close Schließen Reset settings Einstellungen zurücksetzen Save Speichern Calibration Kalibrierung Gyroscope Gyroskop Accelerometer Beschleunigungssensor Selected device doesn't have any inputs to calibrate. Ausgewähltes Gerät hat keine Inputs zum Kalibrieren. Calibration was not saved for the preset. Do you really want to continue? Die Kalibrierung wurde für die Vorgabe nicht gespeichert. Willst du wirklich fortfahren? Do you really want to reset calibration of current device? Willst du die Kalibrierung des aktuellen Geräts wirklich zurücksetzen? Accelerometer calibration sets the neutral controller orientation. Beschleunigungssensor-Kalibrierung legt die neutrale Ausrichtung des Kontrollers fest. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Gyroskop-Kalibrierung korrigiert den Sensor-Offset. Dadurch wird verhindert, dass sich der Mauszeiger bewegt, wenn sich der Kontroller im Ruhezustand befindet. Calibration completed. Kalibrierung abgeschlossen. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Offset-Kalibrierung ist abgeschlossen. Klicke auf "Kalibrierung fortsetzen", um mit der Gain-Kalibrierung fortzufahren. Hold the controller in the desired neutral position and press continue. Halte den Kontroller in der gewünschten neutralen Position und drücke auf Weiter. Calibrating accelerometer Beschleunigungssensor kalibrieren Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Sammeln von Beschleunigungssensor-Daten... Bitte halte den Kontroller ruhig. Dies kann bis zu %1 Sekunden dauern. Place the controller at rest, e.g. put it on the desk, and press continue. Lege den Kontroller zur Seite, z.B. auf den Schreibtisch, und drücke auf Weiter. Calibrating gyroscope Gyroskop kalibrieren Collecting gyroscope data... This can take up to %1 seconds. Sammeln von Gyroskopdaten... Dies kann bis zu %1 Sekunden dauern. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Bewege nun den Steuerknüppel mehrmals bis zum Maximum in verschiedene Richtungen und zurück zur Mitte. Das kann bis zu %1 Sekunde dauern. Calibrating stick Steuerknüppel kalibrieren Continue calibration Kalibrierung fortsetzen Now move the stick in full circles for several times. This can take up to %1 seconds. Bewege den Steuerknüppel nun mehrmals in Vollkreisen. Das kann bis zu %1 Sekunden dauern. Calibration was saved for the preset. Do you really want to reset settings? Die Kalibrierung wurde für die Voreinstellung gespeichert. Willst du die Einstellungen wirklich zurücksetzen? CapturedWindowInfoDialog Captured Window Properties Erkannte Fenstereigenschaften Information About Window Fensterinformationen Class: Klasse: TextLabel Title: Titel: Path: Pfad: Match By Properties Nach Eigenschaften zuordnen Class Klasse Title Titel Path Pfad Full Path vollständiger Pfad File Name Dateinmae DPadContextMenu Mouse (Normal) Maus (Normal) Mouse (Inverted Horizontal) Maus (Invertiert Horizontal) Mouse (Inverted Vertical) Maus (Invertiert Vertikal) Mouse (Inverted Horizontal + Vertical) Maus (Invertiert Horizontal + Vertikal) Arrows Pfeiltasten Keys: W | A | S | D Tasten: W | A | S | D NumPad Nummerntastatur None Nichts Standard Standard Eight Way 8-Weg 4 Way Cardinal 4-Wege kardinal 4 Way Diagonal 4-Wege diagonal Mouse Settings Mauseinstellungen DPadEditDialog Dialog Dialog Presets: Vorgaben: Mouse (Normal) Maus (Normal) Mouse (Inverted Horizontal) Maus (Invertiert Horizontal) Mouse (Inverted Vertical) Maus (Invertiert Vertikal) Mouse (Inverted Horizontal + Vertical) Maus (Invertiert Horizontal + Vertikal) Arrows Pfeiltasten Keys: W | A | S | D Tasten: W | A | S | D NumPad Nummerntastatur None Nichts Dpad Mode: DPad Modus: &Name: &Name: 4 Way Cardinal 4-Wege kardinal 4 Way Diagonal 4-Wege diagonal DPad Delay: DPad-Verzögerung: Time lapsed before a direction change is taken into effect. Zeit abgelaufen bevor eine Richtungsänderung vollzogen wird. s Specify the name of a dpad. Vergebe den Namen des DPads. Mouse Settings Mauseinstellungen Standard Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Standard: 8-Regionen-Dpad mit zwei aktiven Richtungstasten wenn sich der dpad in einem diagonalen Bereich befindet. Acht Weg: 8 Region dpad, wobei jede Richtung ihre eigene dedizierte Taste. Nur eine Taste ist immer aktiv bei zur Zeit. Nützlich für Rouge-ähnliche Spiele. 4-Wege-Kardinal: 4 Region dpad mit Regionen entsprechend die Himmelsrichtungen des dpad. Nützlich für Menüs. 4-Wege-Diagonale: 4-Regionen-Dpad mit jeder Region entsprechend in eine diagonale Zone. Eight Way 8-Wege Set Set Set %1 Set %1 EditAllDefaultAutoProfileDialog Default Profile Standardprofil Profile: Profil: Browse Durchsuchen Open Config Konfiguration öffnen Profile file path is invalid. Profil-Dateipfad ist ungültig. ExtraProfileSettingsDialog Extra Profile Settings Weitere Profileinstellungen Key Press Time: Tastendruckzeit: 0.00 ms 0.00 ms Profile Name: Profilname: s s GameController Game Controller Gamecontroller GameControllerDPad DPad DPad GameControllerMappingDialog Game Controller Mapping Game Controller Zuweisung <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A A B B X X Y Y Back Zurück Start Start Guide Guide Left Shoulder linker Schulterbutton Right Shoulder rechter Schulterbutton Left Stick Click linker Stick Klick Right Stick Click rechter Stick Klick Left Stick X linker Stick X Left Stick Y linker Stick Y Right Stick X rechter Stick X Right Stick Y rechter Stick Y Left Trigger linker Trigger Right Trigger rechter Trigger DPad Up DPad Hoch DPad Left DPad Links DPad Down DPad Runter DPad Right DPad Rechts Mapping Zuweisung SDL 2 Game Controller Mapping String SDL 2 Game Controller Zuweisungsstring Last Axis Event: Letztes Achsenereignis: Current Axis Detection Dead Zone: Aktuelle Achsenerkennungs Totzone: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Spielecontroller Zuweisung (%1) (#%2) Discard Controller Mapping? Controller Zuweisung verwerfen? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. Zuweisung für diesen Controller verwerfen? Wenn verworfen, kehrt der Controller zu einem Joystick zurück wenn alle Joysticks aktualisiert werden. GameControllerSet Back Zurück Guide Handbuch Start Start LS Click LS Klick RS Click RS Klick L Shoulder L Schulter R Shoulder R Schulter L Trigger L Trigger R Trigger R Trigger GameControllerTrigger Trigger Trigger JoyAccelerometerButton Up Hoch Down Runter Left Links Right Rechts Shock Schock JoyAccelerometerSensor Accelerometer Beschleunigungssensor JoyAxis Axis Achse JoyAxisButton Negative Negativ Positive Positiv Unknown Unbekannt Button Button JoyAxisContextMenu Mouse (Horizontal) Maus (Horizontal) Mouse (Inverted Horizontal) Maus (Invertiert Horizontal) Mouse (Vertical) Maus (Vertikal) Mouse (Inverted Vertical) Maus (Invertiert Vertikal) Arrows: Up | Down Pfeiltasten: Hoch | Runter Arrows: Left | Right Pfeiltasten: Links | Rechts Keys: W | S Tasten: W | S Keys: A | D Tasten: A | D NumPad: KP_8 | KP_2 Nummernblock: KP_8 | KP_2 NumPad: KP_4 | KP_6 Nummernblock: KP_4 | KP_6 None Nichts Mouse Settings Mauseinstellungen Left Mouse Button Linke Maustaste Right Mouse Button Rechte Maustaste JoyButton Processing turbo for #%1 - %2 Bearbeitungsturbo für #%1 - %2 Finishing turbo for button #%1 - %2 Finishing-Turbo für Taste #%1 - %2 Distance change for button #%1 - %2 Abstandsänderung für Taste #%1 - %2 Button Button [NO KEY] [KEINE TASTE] [Set %1 1W] [Set %1 1W] [Set %1 2W] [Set %1 2W] [Set %1 WH] [Set %1 WH] JoyButtonContextMenu Toggle Umschalten Turbo Turbo Clear Leeren Set Select Set-Auswahl Disabled Deaktiviert Set %1 Set %1 Set %1 1W Set %1 1W Set %1 2W Set %1 2W Set %1 WH Set %1 WH JoyButtonSlot Mouse Maus Up Hoch Down Runter Left Links Right Rechts LB LB MB MB RB RB Pause Pause Hold Halten Cycle Kreislauf Distance Distanz Release Freigeben Mouse Mod Maus Mod Press Time Druckzeit Delay Verzögerung Load %1 Lade %1 Set Change %1 Gruppewahl %1 [Text] %1 [Text] %1 [Exec] %1 [Exec] %1 [NO KEY] [KEINE TASTE] JoyControlStick Stick Stick JoyControlStickButton Up Hoch Down Runter Left Links Right Rechts Button Button JoyControlStickContextMenu Mouse (Normal) Maus (Normal) Mouse (Inverted Horizontal) Maus (Invertiert Horizontal) Mouse (Inverted Vertical) Maus (Invertiert Vertikal) Mouse (Inverted Horizontal + Vertical) Maus (Invertiert Horizontal + Vertikal) Arrows Pfeiltasten Keys: W | A | S | D Tasten: W | A | S | D NumPad Nummerntastatur None Nichts Standard Standard Eight Way 8-Wege 4 Way Cardinal 4-Wege kardinal 4 Way Diagonal 4-Wege diagonal Mouse Settings Mauseinstellungen JoyControlStickEditDialog Dialog Dialog X: X: 0 0 Y: Y: Distance: Distanz: Presets: Vorgaben: Mouse (Normal) Maus (Normal) Mouse (Inverted Horizontal) Maus (Invertiert Horizontal) Mouse (Inverted Vertical) Maus (Invertiert Vertikal) Mouse (Inverted Horizontal + Vertical) Maus (Invertiert Horizontal + Vertikal) Arrows Pfeiltasten Keys: W | A | S | D Tasten: W | A | S | D NumPad Nummerntastatur None Nichts Stick Mode: Stickmodus: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Standard: 8-Wege-Stick mit zwei Richtungstasten aktiv wenn der Stick in diagonaler Richtung ist. 8-Wege: 8-Wege-Stick mit jedem Weg einer eigenen Taste entsprechend. Nur eine Taste ist gleichzeitig aktiv. Nützlich für "rougelike" Spiele. 4-Wege Kardinal: 4-Regionen-Stick, wobei jede Region einer Kardinal-/Himmelsrichtung des Sticks entspricht. Nützlich für Menüs. 4-Wege Diagonal: 4-Regionen-Stick, wobei jede Region einer Diagonal-Zone des Sticks entspricht. 4 Way Cardinal 4-Wege kardinal 4 Way Diagonal 4-Wege diagonal Modifier Zone: Modifikator Zone: Dead zone value to use for an analog stick. Totzonenwert für Analogsticks. Value when an analog stick is considered moved 100%. Wert für den ein Analogstick als 100% ausgelenkt betrachtet wird. The area (in degrees) that each diagonal region occupies. Den Bereich (in Grad) die jede diagonale Region einnimmt. Square Stick: quadratischer Stick: Percentage to modify a square stick coordinates to confine values to a circle Prozentsatz zur Änderung der Koordinaten einer quadratischen Stick, um die Werte auf einen Kreis zu beschränken % % Stick Delay: Stick Verzögerung: Time lapsed before a direction change is taken into effect. Abgelaufene Zeit bis eine Richtungsänderung wirksam wird. s Modifier: Modifikator: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Bearbeiten-Button, der bei aktivem Stick aktiv ist. Diese Taste ist nützlich für die Zuweisung von Zonen mit Modifikationstasten, die verwendet werden können, um einem analogen Stick Geh-/Sprint-Funktionalität zuzuweisen. PushButton Taste Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Grenzwert bei dem der Modifikator-Button aktiviert wird. Diese Taste ist nützlich für die Zuweisung von Zonen mit Modifikationstasten, die verwendet werden können, um einem analogen Stick Geh-/Sprint-Funktionalität zuzuweisen. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Legt fest, ob die Modifikatortasten aktiviert werden, wenn der Stick innerhalb oder außerhalb des Grenzwertes liegt. Diese Taste ist nützlich für die Zuweisung von Zonen mit Modifikationstasten, die verwendet werden können, um einem analogen Stick Geh-/Sprint-Funktionalität zuzuweisen. Invert Modifier Zone Modifikator Zone invertieren Na&me: Name: Na&me: Specify the name of an analog stick. Vergebe den Namen eines Analogsticks. Mouse Settings Mauseinstellungen Standard Standard Bearing: Bearing: % Safe Zone: % Schutzzone: Eight Way 8-Wege Dead Zone: Dead Zone: Max Zone: Max Zone: Diagonal Range: diagonale Reichweite: Set Gruppe Set %1 Gruppe %1 JoyControlStickModifierButton Modifier Modifikator JoyDPad DPad DPad JoyDPadButton Up Hoch Down Runter Left Links Right Rechts Button Button JoyGyroscopeButton Pitch Up Pitch Hoch Pitch Down Pitch Runter Yaw Left Yaw Links Yaw Right Yaw Rechts Roll Left Roll Linksrum Roll Right Roll Rechtsrum JoyGyroscopeSensor Gyroscope Gyroskop JoySensorButton Button Taste JoySensorContextMenu Mouse Settings Mauseinstellungen JoySensorEditDialog Dialog Dialog 0 0 Acceleration (m/s^2): Beschleunigung (m/s^2): Pitch (°): Pitch (°): Roll (°): Roll (°): % Safe Zone: % Schutzzone: Presets: Vorgaben: Dead Zone: Dead Zone: Dead zone value to use for an analog sensor. Dead Zone Wert, der für einen Analogsensor zu verwenden ist. Max Zone: Max Zone: Value when an analog sensor is considered moved 100%. Wert, bei dem ein Analogsensor als zu 100% bewegt betrachtet wird. Diagonal Range: Diagonale Reichweite: The area (in degrees) that each diagonal region occupies. Den Bereich (in Grad) die jede diagonale Region einnimmt. Sensor Delay: Sensor-Verzögerung: Time lapsed before a direction change is taken into effect. Zeit, die vergeht, bevor eine Richtungsänderung in Kraft tritt. s s Na&me: Na&me: Specify the name of an analog sensor. Gib den Namen eines Analogsensors an. Mouse Settings Mauseinstellungen Roll (°/s) Roll (°/s) Pitch (°/s) Neigung (°/s) Yaw (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None Keine Mouse (Normal) Maus (Normal) Mouse (Inverted Horizontal) Maus (Invertiert Horizontal) Mouse (Inverted Vertical) Maus (Invertiert Vertikal) Mouse (Inverted Horizontal + Vertical) Maus (Invertiert Horizontal + Vertikal) Arrows Pfeiltasten Keys: W | A | S | D Tasten: W | A | S | D NumPad Nummerntastatur JoyTabWidget <New> <Neu> Battery level of controller Batteriestand des Kontrollers Remove Entfernen Remove configuration from recent list. Entferne Konfiguration aus den letzten Einträgen. Load Laden Load configuration file. Lade Konfigurationsdatei. Save Speichern Save changes to configuration file. Änderungen in Konfigurationsdatei speichern. Save As Speichern unter Save changes to a new configuration file. Änderungen in neue Konfigurationsdatei speichern. Sets Gruppen Copy from Set Kopie aus Gruppe Settings Einstellungen Set 1 Gruppe 1 Set 2 Gruppe 2 Set 3 Gruppe 3 Set 4 Gruppe 4 Set 5 Gruppe 5 Set 6 Gruppe 6 Set 7 Gruppe 7 Set 8 Gruppe 8 Stick/Pad Assign Stick/Pad Zuweisung Controller Mapping Controllerzuweisung Quick Set Schnellkonfiguration Names Namen Toggle button name displaying. Buttonnamendarstellung wechseln. Pref Einst Change global profile settings. Globale Profileinstellungen ändern. Reset Reset Revert changes to the configuration. Reload configuration file. Änderungen der Konfiguration zurücksetzen. Neuladen der Konfiguration. Open Config Konfiguration öffnen Config Files (*.amgp *.xml) Konfigurationsdateien (*.amgp *.xml) Config File (*.%1.amgp) Konfigurationsdatei (*.%1.amgp) Do you really want to reset buttons settings for joystick? Willst du wirklich die Einstellungen der Tasten für den Joystick zurücksetzen? Save Profile Changes? Profiländerungen speichern? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Änderungen am neuen Profil wurden nicht gespeichert. Möchten Sie das aktuelle Profil speichern oder verwerfen? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Änderungen am neuen Profil %1 wurden nicht gespeichert. Möchten Sie das aktuelle Profil speichern oder verwerfen? Sticks Sticks Sensors Sensoren DPads DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Es wurden keine Tasten zugewiesen. Bitte verwenden Sie den Schnellkonfiguration um Tasten zuzuweisen oder deaktivieren Sie das Ausblenden leerer Tasten. Set %1: %2 Gruppe %1: %2 Set %1 Gruppe %1 Copy Set Assignments Kopiere Gruppe-Zuweisungen Are you sure you want to copy the assignments and device properties from %1? Sind Sie sicher, dass Sie die Aufgaben-und Geräteeigenschaften von%1 kopieren möchten? Save Config Konfiguration speichern Set Gruppe Joystick Joystick Joystick JoystickStatusWindow Properties Eigenschaften Details Details Name: Name: %1 %1 Number: Nummer: Axes: Achsen: Buttons: Buttons: Hats: Hats: Sensors: Sensoren: Battery: Batterie: Unknown Unbekannt GUID: GUID: Game Controller: Gamecontroller: Axes Achsen Buttons Buttons Hats Hats Sensors Sensoren %1 (#%2) Properties %1 (#%2) Eigenschaften Empty Leer Low Niedrig Medium Mittel Full Voll Wired Kabelgebunden Different: %1 Unterschiedlich: %1 Accelerometer + Gyroscope Beschleunigungssensor + Gyroskop Accelerometer Beschleunigungssensor Gyroscope Gyroskop None Keine Axis %1 Achse %1 Hat %1 Hat %1 No Nein Yes Ja MainSettingsDialog Edit Settings Einstellungen ändern General Allgemein Controller Mappings Controllerzuweisungen Language Sprache Auto Profile Autoprofil Mouse Maus Advanced Fortgeschrittene <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Geben Sie das Standardverzeichnis an, dass das Programm im Dateidialog verwenden soll beim Laden oder Speichern eines Profils.</p></body></html> Recent Profile Count: Einträge an Profilen merken: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Anzahl der Profile, die in den letzten Profilen-Liste platziert werden können. 0 = keine Begrenzung.</p></body></html> Gamepad Poll Rate: Gamepad-Frequenz: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Ändere die Frequenz, die das Programm verwendet, um neue Ereignisse von Gamepads aus zu entdecken. Standardeinstellung: 10 ms. Eine Verringerung des Wertes kann dazu führen, dass die Anwendung mehr CPU-Leistung verbraucht. Teste daher die Einstellung, bevor du AntiMicroX unbeaufsichtigt verwendest. Hide main window when the main window close button is clicked instead of quitting the program. Verstecke Hauptfenster anstatt es zu schließen, wenn die "Schließen"-Schaltfläche gedrückt wurde. Close To Tray Schließen im Tray Have Windows start AntiMicroX at system startup. Lade AntiMicroX beim Systemstart. Launch At Windows Startup Beim Windows-Start starten Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Zeige die zuletzt benutzten Profile aller Controller als eine Liste anstatt als Untermenüs. Single Profile List in Tray Einzelprofil-Menü im Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimiere das Programm in die Taskleiste. Standardmäßig wird AntiMicroX, falls möglich, in das System-Tray minimiert. Minimize to Taskbar In die Taskleiste minimieren This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Diese Option versteckt alle Tasten denen keine Aktion zugeordnet wird. Der Schnelleinstellungs-Dialog muss benutzt werden um die Editier-Einstellungen aufzurufen. Hide Empty Buttons Verstecke leere Schaltflächen When the program is launched, open the last known profile that was opened during the previous session. Wenn das Programm gestartet wurde, öffne das zuletzt benutzte Profil. Auto Load Last Opened Profile Zuletzt geöffnetes Profil automatisch öffnen Only show the system tray icon when the program first launches. Zeige das System-Tray-Icon nur, wenn das Programm zum ersten Mal startet. Launch in Tray Starten im Tray Associate .amgp files with AntiMicroX in Windows Explorer. Assoziiere .amgp-Dateien mit AntiMicroX im Windows Explorer. Associate Profiles Assoziiere Profile Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Denke daran, dass es nicht funktioniert, wenn du diese Tastatur nicht an den Computer angeschlossen hast oder wenn die nicht wie bei Desktop-PCs eingebaut ist Attach the numeric keypad Anschluss einer numerischen Tastatur Key Repeat Tastenanschlag Active keys will be repeatedly pressed when this option is enabled. Dauerhaft gedrückte Tasten werden wiederholt gedrückt, wenn diese Option aktiviert ist. Enable Aktivieren Specifies how much time should elapse before key repeating begins. Bestimmt die Zeit die abläuft bis das Wiederholen des Tastenanschlags beginnt. Specifies how many times key presses will be performed per seconds. Bestimmt wie oft Tastenanschläge pro Sekunde durchgeführt werden. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntiMicroX wurde durch Mitwirkende in viele verschiedene Sprachen übersetzt. Standardmäßig wählt das Programm ein die entsprechende Übersetzung anhand der Einstellung Ihres Systems. Jedoch können Sie AntiMicroX eine andere Übersetzung anhand der Sprache von der Liste hierunter wählen.</p></body></html> Português do Brasil Português do Brasil Français Français Deutsch Deutsch Italiano Italiano 日本語 日本語 Русский Русский српски / srpski српски / srpski 简体中文 简体中文 Español Español українська українська Polski Polski History Si&ze: Historiengrö&ße: Weight Modi&fier: Gewichtsm&odifikator: Log File: Log-Datei: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> <html><head/><body><p><span style=" font-style:italic;">Hinweis Nicht spezifizierte Protokolldatei ermöglicht das Ausgeben von Protokollen in der Konsolenausgabe</span></p></body></html> Log Level: Log-Stufe: None None Error Error Warning Warning Info Info Verbose Ausführlich Debug Debug Note: To see the change of log level in console output (not in log file), application restart is required Hinweis: Um die Änderung des Log-Levels in der Konsolenausgabe (nicht in der Log-Datei) zu sehen, ist ein Neustart der Anwendung erforderlich Reset Reset Class Klasse Title Titel Program Programm Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Deaktiviere die "Zeigerbeschleunigung verbessern" Windowseinstellung während AntiMicroX läuft. Dies erlaubt präzisere Mausbewegungen in AntiMicroX. Disable Enhance Pointer Precision Deaktiviere "Zeigerbeschleunigung verbessern" Smoothing Glättung Refresh Rate: Wiederholrate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Die Aktualisierungsrate ist die Zeitspanne, die zwischen den Mausereignissen vergeht. Seie vorsichtig, wenn du diese Einstellung änderst, da das Programm dadurch mehr CPU-Leistung verbraucht. Wenn du diesen Wert zu niedrig stellst ein, kann dies zu einer Instabilität des Systems führen. Teste die Einstellung, bevor du die unbeaufsichtigt verwendest. Spring Quelle Screen: Bildschirm: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Verwende den angegebenen Bildschirm für den Federmodus. Unter Linux wird standardmäßig der Hauptbildschirm verwendet. Unter Windows ist die Vorgabe, alle verfügbaren Bildschirme zu verwenden. Accel Numerator: Beschleunigungsnumerator: 0 0 Accel Denominator: Beschleunigungsdenominator: Accel Threshold: Beschleunigung Grenze: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Wenn die Beschleunigungswerte für die virtuelle Maus durch einen anderen Prozess geändert wurden, insbesondere beim Beenden eines älteren Spiels, dann möchtest du vielleicht die von der virtuellen Maus verwendeten Beschleunigungswerte zurücksetzen. Reset Acceleration Beschleunigung zurücksetzen Delay: Verzögerung: Pro&file Directory: Profilverzeich&nis: Show low battery notification Benachrichtigung über niedrigen Batteriestand anzeigen Show empty battery notification Benachrichtigung über leeren Batteriestand anzeigen ms ms Rate: Rate: times/s mal/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. Unten finden Sie eine Liste der benutzerdefinierten Zuordnungen, die gespeichert werden können. Sie können die folgende Tabelle verwenden, um Zuordnungen zu löschen bzw. Zuordnungen vorübergehend zu deaktivieren. Sie können auch Abbildungendeaktivieren, die in SDL enthalten sind, nur eine neue Zeile einfügen mit dem entsprechenden Joystick-GUID und prüfen deaktivieren. Die Einstellungen werden nicht wirksam werden, bis Sie entweder alle Joysticks aktualisieren oder diesen bestimmten Joystick trennen. GUID GUID Mapping String Zuweisungsstring Disable? Deaktivieren? Delete Löschen Default Standard English Englisch Active Aktiv Devices: Geräte: All Alles Device Gerät Profile Profil Default? Standard? Add Hinzufügen Edit Editieren AutoProfile (disabled in Wayland) AutoProfile (in Wayland deaktiviert) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Außerdem, Windows-Nutzer die einen geringen Wert nutzen möchten, sollten auch das "Deaktiviere 'Zeigerbeschleunigung verbessern'" Kontrollkästchen aktivieren, wenn die Option nicht in Windows deaktiviert ist. Select Default Profile Directory Wähle das Standard-Profil-Verzeichnis Are you sure you want to delete the profile? Sind Sie sicher, dass Sie das Profil löschen möchten? Save Log File As Speichere Logdatei unter Log Files (*.log) Logdateien (*.log) Do you really want to reset setting? Willst du die Einstellung wirklich zurücksetzen? Would you like to reset mappings too? Möchtest du auch Mappings zurücksetzen? MainWindow No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu Keine Joysticks gefunden. Stecken Sie eine Joystick ein und wählen Sie dann die Option "Joysticks aktualisieren" im Hauptmenü aus If events are not seen by a game, please click here to run this application as Administrator. Wenn Ereignisse von einem Spiel nicht gesehen werden, klicke hier, um diese Anwendung als Administrator auszuführen. Update Button Update Taste &App &Anwendung &Options &Optionen AntiMicroX He&lp Hi&lfe &Quit B&eenden Ctrl+Q Strg+Q &Update Joysticks &Joysticks aktualisieren Ctrl+U Strg+U &Hide &Verstecken Ctrl+H Strg+H &About Ü&ber Ctrl+A Strg+A About &Qt Über &Qt Ctrl+T Ctrl+T &Properties &Eigenschaften Ctrl+P Ctrl+P &Key Checker &Tasteprüfer Ctrl+K Ctrl+K &GitHub Page &GitHub Seite Ctrl+G Ctrl+G S&ettings &Einstellungen Ctrl+S Ctrl+S &Stick/Pad Assign &Stick/Pad-Zuordnung Ctrl+X Ctrl+X &Wiki &Wiki Ctrl+W Ctrl+W &Issues &Issues Ctrl+I Ctrl+I &Calibration &Kalibrierung Ctrl+C Ctrl+C Home Page Webseite (%1) (%1) Open File Datei öffnen Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. Sind Sie sich sicher, dass Sie das Programm als Administrator ausführen wollen? Einige Spiele starten als Administrator, was dazu führt, dass von antimicro ausgelöste Ereignisse von diesen Spielen nicht berücksichtigt werden, außer antimicro wird auch als Administrator ausgeführt. Dies liegt an Berechtigungsproblemen, die durch die Optionen der Benutzerkontensteuerung (User Account Control, UAC) in Windows Vista und höher verursacht werden. %1 battery %1 Batterie Battery level is less than %1 Der Batteriestand beträgt weniger als %1 Device number: %1 Device name: %2 Gerätenummer: %1 Name des Geräts: %2 Update to %1 available Update zu %1 verfügbar Reading old profile Lesen des alten Profils This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 Dieses Profil verwendet die GUID-Nummern der Kontroller. Möchtest du die GUID-Nummern in dieser Datei in UniqueID umwandeln, um sie in identischen Spielkontrollern zu verwenden? Diese alte Datei kann seit Version 2.25 nicht mehr in Antimicrox geladen werden &Restore &Wiederherstellen Calibration couldn't be opened Das Kalibrierungsfenster konnte nicht geöffnet werden You must connect at least one controller to open the window Du muss mindestens einen Controller anschließen, um das Fenster zu öffnen Run as Administrator? Als Administrator ausführen? Failed to elevate program Berechtigungserhöhung fehlgeschlagen Failed to restart this program as the Administrator Neustart als Administrator ist fehlgeschlagen MouseAxisSettingsDialog Mouse Settings - Mauseinstellungen - Set %1 Set %1 MouseButtonSettingsDialog Mouse Settings - Mauseinstellungen - Set %1 Set %1 MouseControlStickSettingsDialog Mouse Settings Mauseinstellungen Set %1 Set %1 MouseDPadSettingsDialog Mouse Settings Mauseinstellungen Set %1 Set %1 MouseSensorSettingsDialog Mouse Settings Mauseinstellungen Set %1 Set %1 MouseSettingsDialog Mouse Settings Mauseinstellungen Mouse Mode: Mausmodus: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Der Zeigermodus wird verwendet, um den Mauszeiger relativ zu der aktuellen Position auf dem Bildschirm zu bewegen je nachdem, wie viel Sie eine Achse bewegen oder wenn eine Taste gedrückt wird. Der Sprungmodus bewegt den Mauspfeil vom Mittelpunkt des Bildschirms je nach Bewegung einer Achse. Der Mauspfeil wandert zu seinem Mittelpunkt, wenn eine Achse zur Dead Zone zurück kehrt. Cursor Zeiger Spring Sprung Acceleration: Beschleunigung: Enhanced Precision Verbesserte Präzision Linear linear Quadratic quadratisch Cubic kubisch Quadratic Extreme extrem quadratisch Power Function Power Funktion Easing Quadratic Erleichternd quadratisch Easing Cubic Erleichternd kubisch Mouse Speed Settings Einstellungen der Mausgeschwindigkeit Enable to change the horizontal and vertical speed boxes at the same time. Aktivieren, um die horizontale und vertikale Geschwindigkeitseinstellungen zur gleichen Zeit zu ändern. Change Together Zusammen ändern Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Optionen, die ermöglichen deiner Mausbewegung mehr Beschleunigung hinzuzufügen, als sich aus der Beschleunigungskurve ergeben hätte. Je nachdem, wie schnell die Achse auf dem Gamepad bewegt wird, wird eine Beschleunigung hinzugefügt. Dies soll helfen, einige der Probleme mit dem sehr begrenzten Eingangsbereich zu umgehen, der bei typischen Gamepad-Analog-Sticks zur Verfügung steht. Delta Acceleration Deltabeschleunigung &Multiplier: &Multiplikator: Mi&n Threshold: Mi&n Grenze: 1 = 20 pps 1 = 20 pps Wheel Hori. Speed: Rad-Gesch. horizontal: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Stellen Sie die Geschwindigkeit für die horizontale Mausrad-Bewegung entsprechend der Anzahl der simulierten Raster pro Sekunde ein. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Stellen Sie die Geschwindigkeit für die vertikale Mausrad-Bewegung entsprechend der Anzahl der simulierten Raster pro Sekunde ein. Sensitivit&y: Sensibilitä&t: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Für die Beschleunigungskurve des Power-funktiones. Gibt den Faktor an, der für die Kurvenempfindlichkeit verwendet werden soll. Wenn der Wert über 1,0 liegt, wird die Mausbewegung am unteren Ende einer Achse schneller beschleunigt. Easing Duration: Erleichternde Dauer: s Highest value to accelerate mouse movement by Höchster Wert zur Beschleunigung der Mausbewegung durch x x Start %: Start %: Acceleration begins at this percentage of the base multiplier Die Beschleunigung beginnt bei diesem Prozentsatz des Basismultiplikators Minimum amount of axis travel required for acceleration to begin Minimaler Achshub zum Starten der Beschleunigung erforderlich Max Threshold: Max Grenze: Maximum axis travel before acceleration has reached the multiplier value Maximaler Achsabstand vor Erreichen des Multiplikator-Beschleunigungswertes E&xtra Duration: zu&sätzliche Dauer: Curve: Kurve: Ease Out Sine Ease Out Sinus Ease Out Quad Ease Out quadratisch Ease Out Cubic Ease Out kubisch Release Radius: Freigabe-Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Wenn aktiviert, Besagt, dass das Ursprungs-arreal durch ein nicht-relativen Ursprung relativ zur Mausposition sein wird. Relative Relativ Mouse Status Maus-Status X: X: 0 (0 pps) 0 (0 pps) Y: Y: 1 = 1 notch(es)/s 1 = 1 Raste Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Erweitert: Dreistufige Kurve, die die Maus bewegen lässt langsam am unteren Ende einer Achse und schnell am oberen Ende. Linear: Die Maus bewegt sich proportional zur Achse. Quadratisch: Die Maus wird am unteren Ende langsam beschleunigt. Kubisch: Kubisch: Die Maus wird langsamer als quadratisch beschleunigt. Quadratisch Extrem: Mausgeschwindigkeit wird einmal um das 1,5-fache erhöht. Der Verfahrweg von 95% der Achsen ist erreicht. Power-Funktion: Ermöglicht eine individuellere Kurvenoption. Erleichternd quadratisch: Quadratisch: Die Achse wird mit Hilfe einer quadratischen Kurve über einen bestimmten Zeitraum allmählich beschleunigt. Erleichternd kubisch: Das obere Ende der Achse wird allmählich beschleunigt über eine Zeitspanne unter Verwendung einer kubischen Kurve. Hori&zontal Speed: hori&zontale Geschwindigkeit: &Vertical Speed: &vertikale& Geschwindigkeit: Wheel Vert. Speed: Rad-Gesch vertikal: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. Gibt die Zeit (in Sekunden) an, die benötigt wird, bevor die Maus nach Erreichen des oberen Endes einer Achse voll beschleunigt wird. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Verlängert die Zeit, während der eine zusätzliche Beschleunigung angewendet wird. Achsbewegungen werden berücksichtigt. Langsameres Flackern reduziert die tatsächliche Zeit, für die eine zusätzliche Beschleunigung angewendet wird. Spring Settings Sprungeinstellungen Spring Width: Sprungweite: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Ändert die Breite der Region, die der Mauszeiger im Sprungmodus zurück legt. 0 wird die gesamte Breite auf Ihrem Bildschirm nutzen. Spring Height: Sprunghöhe: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. Ändert die Höhe der Region, die der Mauszeiger im Sprungmodus zurück legt. 0 wird die gesamte Höhe auf Ihrem Bildschirm nutzen. %n notch(es)/s %n notch/s %n notches/s QKeyDisplayDialog Key Checker Tastenkontrolle <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Ereignisbehandler: Native Key Value: Nativer Tastenwert: 0x00000000 0x00000000 Qt Key Value: Qt-Tastenwert: antimicro Key Value: Wert der Taste (AntiMicroX): QObject Super Super Menu Menü Mute Stummschalten Vol+ Laut+ Vol- Laut- Play/Pause Wiedergabe/Pause Play Wiedergabe Pause Pause Prev Zurück Next Vor Mail E-Mail Home Pos1 Media Medien Search Suche Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Deine ursprünglichen Einstellungen (zuvor in %1 gespeichert) wurden kopiert nach %2 Wenn du willst, kannst du das ursprüngliche Verzeichnis löschen oder es so lassen, wie es ist. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Es ist ein Problem bei der Migration der Einstellungen aufgetreten. Originale Konfigurationen sind gespeichert in %1 aber ihr neuer Speicherort ist: %2 Sie können manuell migrieren, indem Sie das alte Verzeichnis umbenennen und die Datei in antimicrox_settings.ini umbenennen. Quitting Program Beende Programm # of joysticks found: %1 # an Joysticks gefunden: %1 List Joysticks: Liste der Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Versuche Fallback-Option %1 zur Ereignisgenerierung. Failed to open event generator. Exiting. Öffnen des Ereignisgenerators fehlgeschlagen. Breche ab. Using %1 as the event generator. Nutze %1 als Ereignisgenerator. Last button Letzte Taste There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? In den Daten gibt es keine zuletzt vom Gamepad aus gedrückte Taste. Hast du mindestens eine Taste des Gamepads für die Tastatur eingestellt? Unknown log level: Unbekanntes Log-Level Specified contradicting flags: --show and --hidden Angegebene widersprüchliche Flags: --show und --hidden Profile location %1 is not an XML file. Profilort %1 ist keine XML Datei. Profile location %1 does not exist. Profilort %1 existiert nicht. Controller identifier is not a valid value. Controllernummer ist keine gültige Ziffer. An invalid set number '%1' was specified. Es wurde eine ungültige Gruppenummer '%1' angegeben. Controller identifier '%s'' is not a valid value. Der Controller-Bezeichner '%s' ist kein gültiger Wert. No set number was specified. Keine Gruppe gewählt. An invalid event generator was specified. Ein ungültiger Ereignisgenerator wurde angegeben. No event generator string was specified. Kein Ereignesgenerator String wurde angegeben. No log file specified. Keine Logdatei angegeben. xinput version must be at least 2.0. No mouse acceleration changes will occur. xinput Version muss mindestens 2.0 sein. Es wird keine Mausbeschleunigungsänderungen geben. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: Die uinput-Dateien können nicht geöffnet werden. Dies kann zu Problemen bei der Erzeugung von Events führen. Um mögliche Lösungen zu finden, besuche bitte: QuickSetDialog Quick Set Schnellkonfiguration <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>Bitte drücken Sie eine Taste oder bewegen Sie eine Achse auf %1 (<span style=" font-weight:600;">%2</span>).<br/>Dann erscheint ein Dialogfenter, dass Ihnen <br>erlaubt eine Zuordnung zu machen.</p></body></html> Quick Set %1 Schnellkonfiguration %1 SetAxisThrottleDialog Throttle Change Schubänderung The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? Auf Achse %1 wurde der Schub verändert. Möchten Sie die Änderungen an alle Sets übertragen? SetJoystick Set %1: %2 Set %1: %2 Set %1 Set %1 SetNamesDialog Set Name Settings Setnameneinstellungen Set 1 Set 1 Set 2 Set 2 Set 3 Set 3 Set 4 Set 4 Set 5 Set 5 Set 6 Set 6 Set 7 Set 7 Set 8 Set 8 Name Name SimpleKeyGrabberButton Mouse Maus SpringModeRegionPreview Spring Mode Preview Sprungmodus-Vorschau UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Konnte keine gültiges uinput Gerätedatei finden. Bitte überprüfen Sie, ob das uinput Modul geladen ist. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Konnte nicht uinput Gerätedatei öffnen Bitte überprüfen Sie ob Sie die Berechtigung haben auf dieses Gerät zu schreiben Using uinput device file %1 Nutze uinput Gerätedatei %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - = BackSpace Rücktaste Tab Tabulator [ ] \ CapsLock Feststell ; ' Enter Eingabe Shift_L Umschalt_L , . / Ctrl_L Strg_L Super_L Super_L Alt_L Alt_L Space Leertaste Alt_R Alt_R Menu Menü Ctrl_R Strg_R Shift_R Umschalt_R Up Hoch Left Links Down Runter Right Rechts PrtSc Druck Ins Einfg Del Entf Home Pos1 End Ende PgUp Bild ↑ PgDn Bild ↓ NumLock * + KP_Enter KP_Enter KP_1 KP_1 KP_2 KP_2 KP_3 KP_3 KP_4 KP_4 KP_5 KP_5 KP_6 KP_6 KP_7 KP_7 KP_8 KP_8 KP_9 KP_9 KP_0 KP_0 SCLK Rol ↓ Pause Pause Super_R Mute Stumm VolDn Vol- VolUp Vol+ Play Wiedergabe Stop Stoppen Prev Zurück Next Vor [NO KEY] [KEINE TASTE] UnixWindowInfoDialog Captured Window Properties Erkannte Fenstereigenschaften Information About Window Informationen über das Fenster Class: Klasse: TextLabel TextEtikett Title: Titel: Path: Pfad: Match By Properties Nach Eigenschaften zuordnen Class Klasse Title Titel Path Pfad VDPad VDPad VDPad VirtualKeyPushButton Space Leertaste Tab Shift (L) Umschalt (L) Shift (R) Umschalt (R) Ctrl (L) Strg (L) Ctrl (R) Strg (R) Alt (L) Alt (L) Alt (R) Alt (R) Alt Gr Alt Gr ` ~ - = [ ] \ Caps Feststell ; ' , . / ESC PRTSC Drucken SCLK Rollen INS Einfg PGUP Bild ↑ DEL Entf PGDN Bild ↓ 1 2 3 4 5 6 7 8 9 0 NUM LK NUM LOCK * + Enter Eingabe Del Entf < : Super (L) Menu Menü Up Hoch Down Runter Left Links Right Rechts VirtualKeyboardMouseWidget Keyboard Tastatur Mouse Maus Mouse Settings Mauseinstellungen Left Mouse Links Up Mouse Hoch Left Button Mouse Linke Taste Middle Button Mouse Mittlere Taste Right Button Mouse Rechte Taste Wheel Up Mouse Mausrad hoch Wheel Left Mouse Mausrad links Wheel Right Mouse Mausrad rechts Wheel Down Mouse Mausrad runter Down Mouse Runter Right Mouse Rechts Button 4 Mouse Taste 4 Mouse 8 Mouse Taste 8 Button 5 Mouse Taste 5 Mouse 9 Mouse Taste 9 NONE KEINE [NO KEY] [KEINE TASTE] Last button Letzte Taste Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Slots für die Tasten konnten nicht gelöscht werden, da es keine Taste für das Gamepad auf der Tastatur gab. Belege mindestens eine Taste von der Tastatur für das Gamepad Others Andere Applications Anwendungen Browser Back Browser Back Browser Favorites Browser Favorites Browser Forward Browser Forward Browser Home Browser Home Browser Refresh Browser Refresh Browser Search Browser Search Browser Stop Browser Stop Calc Calc Email E-Mail F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media Media Media Next Media Next Media Play Media Play Media Previous Media Previous Media Stop Media Stop Search Suche Volume Down Volume Down Volume Mute Volume Mute Volume Up Volume Up VirtualMousePushButton INVALID UNGÜLTIG WinAppProfileTimerDialog Capture Application Wähle Applikation After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Wählen Sie das Fenster aus mit dem Sie das Profil assozieren möchten, nachdem Sie auf den "Wähle Applikation" Button geklickt haben. Die aktive Applikation wird nach der angegebenen Zahl an Sekunden ausgewählt. Timer: Zeitschaltuhr: Seconds Sekunden Cancel Abbrechen WinExtras [NO KEY] [KEINE TASTE] AntiMicro Profile AntiMicro-Profil X11Extras ESC Tab Tabulator Space Leertaste DEL Entf Return Eingabe KP_Enter KP_Enter Backspace Rücktaste Alt Gr Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput Erweiterung wurde nicht gefunden. Es wird keine Mausbeschleunigungsänderungen geben. xinput version must be at least 2.0. No mouse acceleration changes will occur. xinput Version muss mindestens 2.0 sein. Es wird keine Mausbeschleunigungsänderungen geben. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 PtrFeedbackCalls wurde nicht für den virtuellen Mauszeiger gefunden. Es wird keine Mausbeschleunigungsänderungen für das Gerät mit id=%1 geben Changing mouse acceleration for device with id=%1 Ändere Mausbeschleunigung für Gerät der id=%1 XMLConfigReader Could not write updated profile XML to file %1. Konnte aktuelles Profil nicht als XML in Datei %1 schreiben. XMLConfigWriter Could not write to profile at %1. Konnte Profil nicht schreiben in %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Grafisches Programm zur Zuordnung von Tastatur- und Maussteuerungen zu einem Gamepad. Nützlich für das Spielen von Spielen ohne Gamepad-Unterstützung. main Launch program in system tray only. Nur im Systemtray starten. Launch program with the tray menu disabled Starte das Programm mit deaktiviertem Traymenü Launch program without the main window displayed Starte das Programm, ohne das Hauptfenster anzuzeigen Show app window when hidden. (Used for unhiding window of already running app instance). App-Fenster anzeigen, wenn versteckt. (Wird verwendet, um das Fenster einer bereits laufenden App-Instanz wieder anzuzeigen). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers Starte das Programm mit der Konfigurationsdatei, die als Standard für die ausgewählten Kontroller ausgewählt wurde, oder ändere das aktive Profil der laufenden App. Standardmäßig für alle Kontroller location Location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID Konfigurationsdatei auf einen bestimmten Controller anwenden. Der Wert kann ein Controller-Index, ein Name oder eine GUID sein value Wert Unload currently enabled profile(s) Aktuell aktivierte(s) Profil(e) entladen value(s) Wert(e) Start joysticks on a specific set. Value can be a controller index, name, or GUID Starte Joysticks auf einem bestimmten Satz. Der Wert kann ein Controller-Index, ein Name oder eine GUID sein number value Nummernwert Enable logging. Levels (from the least strict): warn,info,verbose,debug Aktiviere Logging. Levels (von am wenigsten streng): warn,info,verbose,debug log-type Log-type Choose a file for logs writing Wähle eine Datei zum Schreiben von Loggen filename Dateiname Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. Wähle zwischen der Verwendung von XTest-Unterstützung und der Unterstützung von uinput für die Ereigniserzeugung. Verwende nur, wenn du die Optionen xtest und uinput unter Linux oder vmulti unter Windows aktiviert hast. Voreinstellung: xtest. event-generation-type event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. Drucke Informationen über von SDL erkannte Joysticks aus. Verwende nur, wenn du über eine sdl-Bibliothek verfügst. Du kannst den Index, den Namen oder sogar die GUID Ihres Controllers überprüfst. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_en.ts000066400000000000000000013216711471077622000273740ustar00rootroot00000000000000 AboutDialog About About Version Version Info Info Changelog Changelog Credits Credits AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development About Development "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Copyright: 2013 - 2022 License License Program Version %1 Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Program Compiled on %1 at %2 Built Against SDL %1 Built Against SDL %1 Running With SDL %1 Running With SDL %1 Using Qt %1 Using Qt %1 Using Event Handler: %1 Using Event Handler: %1 AddEditAutoProfileDialog Auto Profile Dialog Auto Profile Dialog Pro&file: Pro&file: Browse Browse Window: Window: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Select Window. Click on the appropriate application window and the application file path will be populated in the form. Detect Window Properties Detect Window Properties &Class: &Class: T&itle: T&itle: set partial title set partial title Application: Application: Select Select De&vices: De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Set as Default for Controller Set as Default for Controller A different profile is already selected as the default for this device. A different profile is already selected as the default for this device. Current (%1) Current (%1) Open Config Open Config Select Program Select Program Programs (*.exe) Programs (*.exe) Please use the main default profile selection. Please use the main default profile selection. Main Profile Main Profile Already selected Already selected Chosen Profile Chosen Profile The selection will be used instead of the all default profile option. The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. Please select a window by using the mouse. Press Escape if you want to cancel. Capture Application Window Capture Application Window Could not obtain information for the selected window. Could not obtain information for the selected window. Application Capture Failed Application Capture Failed Profile file path is invalid. Profile file path is invalid. No window matching property was specified. No window matching property was specified. Program path is invalid or not executable. Program path is invalid or not executable. File is not an .exe file. File is not an .exe file. No window matching property was selected. No window matching property was selected. AdvanceButtonDialog Advanced Advanced Assignments Assignments Toggle Toggle Turbo Turbo Set Selector Set Selector Blank or KB/M Blank or KB/M Hold Hold Pause Pause Cycle Cycle Distance Distance Insert Insert Delete Delete Clear All Clear All Time: Time: 0.01s 0.01s 0s 0s Insert a pause that occurs in between key presses. Insert a pause that occurs in between key presses. Release Release Insert a new blank slot. Insert a new blank slot. Delete a slot. Delete a slot. Clear all currently assigned slots. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. Specify the duration of an inserted Pause or Hold slot. 0m 0m &Mouse Speed Mod: &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: Distance: % % Mouse Mod Mouse Mod Press Time Press Time Delay Delay Execute Execute Load Load Set Change Set Change Text Entry Text Entry Join Join Split Split Placeholder Placeholder 0 0 Set the percentage that mouse speeds will be modified by. Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After Auto Reset Cycle After seconds seconds Executable: Executable: ... ... Arguments: Arguments: Enabled Enabled Mode: Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Normal Gradient Gradient Pulse Pulse Delay: Delay: 0.10s 0.10s Rate: Rate: 10.0/s 10.0/s Disabled Disabled Select Set 1 One Way Select Set 1 One Way Select Set 1 Two Way Select Set 1 Two Way Select Set 1 While Held Select Set 1 While Held Select Set 2 One Way Select Set 2 One Way Select Set 2 Two Way Select Set 2 Two Way Select Set 2 While Held Select Set 2 While Held Select Set 3 One Way Select Set 3 One Way Select Set 3 Two Way Select Set 3 Two Way Select Set 3 While Held Select Set 3 While Held Select Set 4 One Way Select Set 4 One Way Select Set 4 Two Way Select Set 4 Two Way Select Set 4 While Held Select Set 4 While Held Select Set 5 One Way Select Set 5 One Way Select Set 5 Two Way Select Set 5 Two Way Select Set 5 While Held Select Set 5 While Held Select Set 6 One Way Select Set 6 One Way Select Set 6 Two Way Select Set 6 Two Way Select Set 6 While Held Select Set 6 While Held Select Set 7 One Way Select Set 7 One Way Select Set 7 Two Way Select Set 7 Two Way Select Set 7 While Held Select Set 7 While Held Select Set 8 One Way Select Set 8 One Way Select Set 8 Two Way Select Set 8 Two Way Select Set 8 While Held Select Set 8 While Held [NO KEY] [NO KEY] sec. sec. /sec. /sec. Not checked slots Not checked slots To delete slots, you need to select at least one To delete slots, you need to select at least one To insert slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Unknown current slot Click on chosen slots before joining them Click on chosen slots before joining them Not enough slots Not enough slots It's impossible to join slots. Add at least one other slot. It's impossible to join slots. Add at least one other slot. Not selected slots Not selected slots It's impossible to join slots. Select at least two slots before joining them It's impossible to join slots. Select at least two slots before joining them Only keyboard slots Only keyboard slots It's only possible to join simple and mix keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. It's impossible to split slots. Add at least one other slot. Not selected slot Not selected slot Select your slot before splitting. Select your slot before splitting. Too many mix slots Too many mix slots Select one mix slot. Select one mix slot. Only mix slots Only mix slots It's only possible to split mix slot. It's only possible to split mix slot. Empty execution path Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist File doesn't exist There is no such file locally, that could be executed. Check the file on your system There is no such file locally, that could be executed. Check the file on your system Set %1 Set %1 Select Set %1 Select Set %1 One Way One Way Two Way Two Way While Held While Held Choose Executable Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Choose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Execute program when slot is activated. Choose Profile Choose Profile Config Files (*.amgp *.xml) Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Stick/Pad Assignment Sticks Sticks DPads DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) %1 (Joystick %2) Stick 1 Stick 1 Enabled Enabled Assign Assign X Axis: X Axis: Y Axis: Y Axis: Stick 2 Stick 2 Number of Physical DPads: %1 Number of Physical DPads: %1 Virtual DPad 1 Virtual DPad 1 Up: Up: Down: Down: Left: Left: Right: Right: Axis %1 Axis %1 Axis %1 - Axis %1 - Axis %1 + Axis %1 + Button %1 Button %1 Move stick 1 along the X axis Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the X axis Move stick 2 along the Y axis Move stick 2 along the Y axis Press a button or move an axis Press a button or move an axis AxisEditDialog Axis Axis Mouse (Horizontal) Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Vertical) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Up | Down Arrows: Left | Right Arrows: Left | Right Keys: W | S Keys: W | S Keys: A | D Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 NumPad: KP_4 | KP_6 None None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Negative Half Throttle Positive Half Throttle Positive Half Throttle Haptic Trigger: Name: Name: Specify the name of an axis. Specify the name of an axis. Mouse Settings Mouse Settings Set the value of the dead zone for an axis. Set the value of the dead zone for an axis. Presets: Presets: Dead Zone: Dead Zone: Max Zone: Max Zone: [NO KEY] [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Negative Throttle Normal Normal Positive Throttle Positive Throttle Current Value: Current Value: Set Set Set %1 Set %1 Left Mouse Button Left Mouse Button Right Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Placeholder Toggle Toggle Enables a key press or release to only occur when a controller button is pressed. Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Enables rapid key presses and releases. Turbo controller. Turbo Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Attach the numeric keypad Last keyboard/mouse button: Last keyboard/mouse button: Slots Slots Na&me: Na&me: Specify the name of a button. Specify the name of a button. Action: Action: Specify the action that will be performed in game while this button is being used. Specify the action that will be performed in game while this button is being used. Advanced Advanced Choose your keyboard key Choose your keyboard key No button No button Last button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice No choice Before you open window with advanced settings, you have to choice a key Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set As last gamepad button has been set Index %1 Index %1 Calibration Form Form Input to calibrate: Steps Z TextLabel TextLabel X X gain offset Y Y Start calibration Start calibration Close Reset settings Reset settings Save Save Calibration Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Captured Window Properties Information About Window Information About Window Class: Class: TextLabel TextLabel Title: Title: Path: Path: Match By Properties Match By Properties Class Class Title Title Path Path Full Path Full Path File Name File Name DPadContextMenu Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad None None Standard Standard Eight Way Eight Way 4 Way Cardinal 4 Way Cardinal 4 Way Diagonal 4 Way Diagonal Mouse Settings Mouse Settings DPadEditDialog Dialog Dialog Presets: Presets: Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad None None Dpad Mode: Dpad Mode: &Name: &Name: 4 Way Cardinal 4 Way Cardinal 4 Way Diagonal 4 Way Diagonal DPad Delay: DPad Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Specify the name of a dpad. Specify the name of a dpad. Mouse Settings Mouse Settings Standard Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Eight Way Set Set Set %1 Set %1 EditAllDefaultAutoProfileDialog Default Profile Default Profile Profile: Profile: Browse Browse Open Config Open Config Profile file path is invalid. Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Extra Profile Settings Key Press Time: Key Press Time: 0.00 ms 0.00 ms Profile Name: Profile Name: s s GameController Game Controller Game Controller GameControllerDPad DPad DPad GameControllerMappingDialog Game Controller Mapping Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A A B B X X Y Y Back Back Start Start Guide Guide Left Shoulder Left Shoulder Right Shoulder Right Shoulder Left Stick Click Left Stick Click Right Stick Click Right Stick Click Left Stick X Left Stick X Left Stick Y Left Stick Y Right Stick X Right Stick X Right Stick Y Right Stick Y Left Trigger Left Trigger Right Trigger Right Trigger DPad Up DPad Up DPad Left DPad Left DPad Down DPad Down DPad Right DPad Right Mapping Mapping SDL 2 Game Controller Mapping String SDL 2 Game Controller Mapping String Last Axis Event: Last Axis Event: Current Axis Detection Dead Zone: Current Axis Detection Dead Zone: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Back Guide Guide Start Start LS Click LS Click RS Click RS Click L Shoulder L Shoulder R Shoulder R Shoulder L Trigger L Trigger R Trigger R Trigger GameControllerTrigger Trigger Trigger JoyAccelerometerButton Up Up Down Down Left Left Right Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis Axis JoyAxisButton Negative Negative Positive Positive Unknown Unknown Button Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Vertical) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Up | Down Arrows: Left | Right Arrows: Left | Right Keys: W | S Keys: W | S Keys: A | D Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 NumPad: KP_4 | KP_6 None None Mouse Settings Mouse Settings Left Mouse Button Left Mouse Button Right Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Distance change for button #%1 - %2 Button Button [NO KEY] [NO KEY] [Set %1 1W] [Set %1 1W] [Set %1 2W] [Set %1 2W] [Set %1 WH] [Set %1 WH] JoyButtonContextMenu Toggle Toggle Turbo Turbo Clear Clear Set Select Set Select Disabled Disabled Set %1 Set %1 Set %1 1W Set %1 1W Set %1 2W Set %1 2W Set %1 WH Set %1 WH JoyButtonSlot Mouse Mouse Up Up Down Down Left Left Right Right LB LB MB MB RB RB Pause Pause Hold Hold Cycle Cycle Distance Distance Release Release Mouse Mod Mouse Mod Press Time Press Time Delay Delay Load %1 Load %1 Set Change %1 Set Change %1 [Text] %1 [Text] %1 [Exec] %1 [Exec] %1 [NO KEY] [NO KEY] JoyControlStick Stick Stick JoyControlStickButton Up Up Down Down Left Left Right Right Button Button JoyControlStickContextMenu Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad None None Standard Standard Eight Way Eight Way 4 Way Cardinal 4 Way Cardinal 4 Way Diagonal 4 Way Diagonal Mouse Settings Mouse Settings JoyControlStickEditDialog Dialog Dialog X: X: 0 0 Y: Y: Distance: Distance: Presets: Presets: Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad None None Stick Mode: Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Cardinal 4 Way Diagonal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. The area (in degrees) that each diagonal region occupies. Square Stick: Square Stick: Percentage to modify a square stick coordinates to confine values to a circle Percentage to modify a square stick coordinates to confine values to a circle % % Stick Delay: Stick Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Modifier: Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Na&me: Specify the name of an analog stick. Specify the name of an analog stick. Mouse Settings Mouse Settings Standard Standard Bearing: Bearing: % Safe Zone: % Safe Zone: Eight Way Eight Way Dead Zone: Dead Zone: Max Zone: Max Zone: Diagonal Range: Diagonal Range: Set Set Set %1 Set %1 JoyControlStickModifierButton Modifier Modifier JoyDPad DPad DPad JoyDPadButton Up Up Down Down Left Left Right Right Button Button JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Button JoySensorContextMenu Mouse Settings Mouse Settings JoySensorEditDialog Dialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Safe Zone: Presets: Presets: Dead Zone: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: Diagonal Range: The area (in degrees) that each diagonal region occupies. The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Na&me: Na&me: Specify the name of an analog sensor. Mouse Settings Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None None Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad JoyTabWidget <New> <New> Battery level of controller Remove Remove Remove configuration from recent list. Remove configuration from recent list. Load Load Load configuration file. Load configuration file. Save Save Save changes to configuration file. Save changes to configuration file. Save As Save As Save changes to a new configuration file. Save changes to a new configuration file. Sets Sets Copy from Set Copy from Set Settings Settings Set 1 Set 1 Set 2 Set 2 Set 3 Set 3 Set 4 Set 4 Set 5 Set 5 Set 6 Set 6 Set 7 Set 7 Set 8 Set 8 Stick/Pad Assign Stick/Pad Assign Controller Mapping Controller Mapping Quick Set Quick Set Names Names Toggle button name displaying. Toggle button name displaying. Pref Pref Change global profile settings. Change global profile settings. Reset Reset Revert changes to the configuration. Reload configuration file. Revert changes to the configuration. Reload configuration file. Open Config Open Config Config Files (*.amgp *.xml) Config Files (*.amgp *.xml) Config File (*.%1.amgp) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Do you really want to reset buttons settings for joystick? Save Profile Changes? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sticks Sensors DPads DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1: %2 Set %1 Set %1 Copy Set Assignments Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Are you sure you want to copy the assignments and device properties from %1? Save Config Save Config Set Set Joystick Joystick Joystick JoystickStatusWindow Properties Properties Details Details Name: Name: %1 %1 Number: Number: Axes: Axes: Buttons: Buttons: Hats: Hats: Sensors: Battery: Battery: Unknown Unknown GUID: GUID: Game Controller: Game Controller: Axes Axes Buttons Buttons Hats Hats Sensors %1 (#%2) Properties %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None None Axis %1 Axis %1 Hat %1 Hat %1 No No Yes Yes MainSettingsDialog Edit Settings Edit Settings General General Controller Mappings Controller Mappings Language Language Auto Profile Auto Profile Mouse Mouse Advanced Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Close To Tray Have Windows start AntiMicroX at system startup. Have Windows start AntiMicroX at system startup. Launch At Windows Startup Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Only show the system tray icon when the program first launches. Launch in Tray Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Attach the numeric keypad Key Repeat Key Repeat Active keys will be repeatedly pressed when this option is enabled. Active keys will be repeatedly pressed when this option is enabled. Enable Enable Specifies how much time should elapse before key repeating begins. Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Português do Brasil Français Français Deutsch Deutsch Italiano Italiano 日本語 日本語 Русский Русский српски / srpski српски / srpski 简体中文 简体中文 Español Español українська українська Polski Polski History Si&ze: History Si&ze: Weight Modi&fier: Weight Modi&fier: Log File: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: Log Level: None None Error Error Warning Warning Info Info Verbose Debug Debug Note: To see the change of log level in console output (not in log file), application restart is required Note: To see the change of log level in console output (not in log file), application restart is required Reset Reset Class Class Pro&file Directory: Pro&file Directory: Show low battery notification Show empty battery notification Title Title Program Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Disable Enhance Pointer Precision Smoothing Smoothing Refresh Rate: Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Spring Screen: Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: Accel Numerator: 0 0 Accel Denominator: Accel Denominator: Accel Threshold: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Reset Acceleration Delay: Delay: ms ms Rate: Rate: times/s times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID GUID Mapping String Mapping String Disable? Disable? Delete Delete Default Default English English Active Active Devices: Devices: All All Device Device Profile Profile Default? Default? Add Add Edit Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Select Default Profile Directory Are you sure you want to delete the profile? Are you sure you want to delete the profile? Save Log File As Save Log File As Log Files (*.log) Log Files (*.log) Do you really want to reset setting? Do you really want to reset setting? Would you like to reset mappings too? Would you like to reset mappings too? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &App &Options &Options He&lp He&lp &Quit &Quit Ctrl+Q Ctrl+Q &Update Joysticks &Update Joysticks Ctrl+U Ctrl+U &Hide &Hide Ctrl+H Ctrl+H &About &About Ctrl+A Ctrl+A About &Qt About &Qt Ctrl+T Ctrl+T &Properties &Properties Ctrl+P Ctrl+P &Key Checker &Key Checker Ctrl+K Ctrl+K &GitHub Page &GitHub Page Ctrl+G Ctrl+G S&ettings S&ettings Ctrl+S Ctrl+S &Stick/Pad Assign &Stick/Pad Assign Ctrl+X Ctrl+X &Wiki &Wiki Ctrl+W Ctrl+W &Issues &Issues Ctrl+I Ctrl+I &Calibration &Calibration Ctrl+C Ctrl+C Home Page Home Page (%1) (%1) Open File Open File Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. Are you sure that you want to run this program as Administrator? Some games run as Administrator, which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Administrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery %1 battery Battery level is less than %1 Battery level is less than %1 Device number: %1 Device name: %2 Device number: %1 Device name: %2 Update to %1 available Reading old profile Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore &Restore Calibration couldn't be opened Calibration couldn't be opened You must connect at least one controller to open the window You must connect at least one controller to open the window Run as Administrator? Run as Administrator? Failed to elevate program Failed to elevate program Failed to restart this program as the Administrator Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Mouse Settings - Set %1 Set %1 MouseButtonSettingsDialog Mouse Settings - Mouse Settings - Set %1 Set %1 MouseControlStickSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseDPadSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSensorSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSettingsDialog Mouse Settings Mouse Settings Mouse Mode: Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Cursor Spring Spring Acceleration: Acceleration: Enhanced Precision Enhanced Precision Linear Linear Quadratic Quadratic Cubic Cubic Quadratic Extreme Quadratic Extreme Power Function Power Function Easing Quadratic Easing Quadratic Easing Cubic Easing Cubic Mouse Speed Settings Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Enable to change the horizontal and vertical speed boxes at the same time. Change Together Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration Delta Acceleration &Multiplier: &Multiplier: Mi&n Threshold: Mi&n Threshold: 1 = 20 pps 1 = 20 pps Wheel Hori. Speed: Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: Easing Duration: s s Highest value to accelerate mouse movement by Highest value to accelerate mouse movement by x x Start %: Start %: Acceleration begins at this percentage of the base multiplier Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Minimum amount of axis travel required for acceleration to begin Max Threshold: Max Threshold: Maximum axis travel before acceleration has reached the multiplier value Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: E&xtra Duration: Curve: Curve: Ease Out Sine Ease Out Sine Ease Out Quad Ease Out Quad Ease Out Cubic Ease Out Cubic Release Radius: Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Relative Mouse Status Mouse Status X: X: 0 (0 pps) 0 (0 pps) Y: Y: 1 = 1 notch(es)/s 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: Hori&zontal Speed: &Vertical Speed: &Vertical Speed: Wheel Vert. Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Settings Spring Width: Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s %n notch/s %n notches/s QKeyDisplayDialog Key Checker Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Event Handler: Native Key Value: Native Key Value: 0x00000000 0x00000000 Qt Key Value: Qt Key Value: antimicro Key Value: AntiMicroX Key Value: QObject Super Super Menu Menu Mute Mute Vol+ Vol+ Vol- Vol- Play/Pause Play/Pause Play Play Pause Pause Prev Prev Next Next Mail Mail Home Home Media Media Search Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program Quitting Program # of joysticks found: %1 # of joysticks found: %1 List Joysticks: List Joysticks: --------------- --------------- Joystick %1: Joystick %1: Attempting to use fallback option %1 for event generation. Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Failed to open event generator. Exiting. Using %1 as the event generator. Using %1 as the event generator. Last button Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 is not an XML file. Profile location %1 does not exist. Profile location %1 does not exist. Controller identifier is not a valid value. Controller identifier is not a valid value. An invalid set number '%1' was specified. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. Controller identifier '%s'' is not a valid value. No set number was specified. No set number was specified. An invalid event generator was specified. An invalid event generator was specified. No event generator string was specified. No event generator string was specified. Unknown log level: No log file specified. No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 Quick Set %1 SetAxisThrottleDialog Throttle Change Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1: %2 Set %1 Set %1 SetNamesDialog Set Name Settings Set Name Settings Set 1 Set 1 Set 2 Set 2 Set 3 Set 3 Set 4 Set 4 Set 5 Set 5 Set 6 Set 6 Set 7 Set 7 Set 8 Set 8 Name Name SimpleKeyGrabberButton Mouse Mouse SpringModeRegionPreview Spring Mode Preview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 Using uinput device file %1 UInputHelper a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z Esc Esc F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace BackSpace Tab Tab [ [ ] ] \ \ CapsLock CapsLock ; ; ' ' Enter Enter Shift_L Shift_L , , . . / / Ctrl_L Ctrl_L Super_L Super_L Alt_L Alt_L Space Space Alt_R Alt_R Menu Menu Ctrl_R Ctrl_R Shift_R Shift_R Up Up Left Left Down Down Right Right PrtSc PrtSc Ins Ins Del Del Home Home End End PgUp PgUp PgDn PgDn NumLock NumLock * * + + KP_Enter KP_Enter KP_1 KP_1 KP_2 KP_2 KP_3 KP_3 KP_4 KP_4 KP_5 KP_5 KP_6 KP_6 KP_7 KP_7 KP_8 KP_8 KP_9 KP_9 KP_0 KP_0 SCLK SCLK Pause Pause Super_R Super_R Mute Mute VolDn VolDn VolUp VolUp Play Play Stop Stop Prev Prev Next Next [NO KEY] [NO KEY] UnixWindowInfoDialog Captured Window Properties Captured Window Properties Information About Window Information About Window Class: Class: TextLabel TextLabel Title: Title: Path: Path: Match By Properties Match By Properties Class Class Title Title Path Path VDPad VDPad VDPad VirtualKeyPushButton Space Space Tab Tab Shift (L) Shift (L) Shift (R) Shift (R) Ctrl (L) Ctrl (L) Ctrl (R) Ctrl (R) Alt (L) Alt (L) Alt (R) Alt (R) Alt Gr Alt Gr ` ` ~ ~ - - = = [ [ ] ] \ \ Caps Caps ; ; ' ' , , . . / / ESC ESC PRTSC PRTSC SCLK SCLK INS INS PGUP PGUP DEL DEL PGDN PGDN 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK NUM LK * * + + Enter Enter Del Del < < : : Super (L) Super (L) Menu Menu Up Up Down Down Left Left Right Right VirtualKeyboardMouseWidget Keyboard Keyboard Mouse Mouse Mouse Settings Mouse Settings Left Mouse Left Up Mouse Up Left Button Mouse Left Button Middle Button Mouse Middle Button Right Button Mouse Right Button Wheel Up Mouse Wheel Up Wheel Left Mouse Wheel Left Wheel Right Mouse Wheel Right Wheel Down Mouse Wheel Down Down Mouse Down Right Mouse Right Button 4 Mouse Button 4 Mouse 8 Mouse Mouse 8 Button 5 Mouse Button 5 Mouse 9 Mouse Mouse 9 NONE NONE [NO KEY] [NO KEY] Last button Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Others Applications Applications Browser Back Browser Back Browser Favorites Browser Favorites Browser Forward Browser Forward Browser Home Browser Home Browser Refresh Browser Refresh Browser Search Browser Search Browser Stop Browser Stop Calc Calc Email Email F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media Media Media Next Media Next Media Play Media Play Media Previous Media Previous Media Stop Media Stop Search Search Volume Down Volume Down Volume Mute Volume Mute Volume Up Volume Up VirtualMousePushButton INVALID INVALID WinAppProfileTimerDialog Capture Application Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Timer: Seconds Seconds Cancel Cancel WinExtras [NO KEY] [NO KEY] AntiMicro Profile X11Extras ESC ESC Tab Tab Space Space DEL DEL Return Return KP_Enter KP_Enter Backspace Backspace Alt Gr Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program in system tray only. Launch program with the tray menu disabled Launch program with the tray menu disabled Launch program without the main window displayed Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value value Unload currently enabled profile(s) Unload currently enabled profile(s) value(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID Start joysticks on a specific set. Value can be a controller index, name, or GUID number value number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type log-type Choose a file for logs writing Choose a file for logs writing filename filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_es.ts000066400000000000000000013731351471077622000274030ustar00rootroot00000000000000 AboutDialog About Acerca de Version Versión <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Desarrollado originalmente por Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next mantenido por el grupo AntiMicro en https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Luego por juliagoda en https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Ahora mantenido en https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Colaboradores:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Traductores:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Portugués brasileño</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chino</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - Francés</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - Alemán</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Phob - alemán</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japonés</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Ruso</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbio</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ucraniano</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Español</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italiano</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polaco</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. "pktiuk" (desde agosto de 2020) Solo quería asegurarme de que esta pieza de software tan útil no fuera abandonada, así que decidí continuar brindando apoyo a este proyecto y hacerlo tan ampliamente accesible como fuera posible. "juliagoda" (desde marzo de 2018 hasta 2020) Queriendo jugar a mis juegos favoritos sin soporte para mandos, encontré este proyecto (que asocia teclas del teclado y botones del ratón a los mandos conectados en Linux) como el más apropiado y reciente. Pero debido a las malas elecciones de esta aplicación en Internet, y como no compilaba correctamente, decidí rescatar el proyecto.Sin embargo, una vez acabado mi trabajo (suficiente para disfrutar jugando) pensé en compartir este código con los demás. Por supuesto permanecerá toda la información sobre los programadores anteriores. "Ryochan7" (desde el 30 de diciembre de 2012 hasta 2017) He estado trabajando en AntiMicro en mis ratos libres. Lo que empezó en un principio como una bifurcación de QJoyPad y una forma de aprender la correcta programación orientada a eventos se volvió algo mucho más grande de lo que pretendía originalmente. Aunque he gastado mucho tiempo aprendiendo nuevas técnicas, encontrando más acerca del ámbito de la emulación KB+M y gastando noches de viernes golpeando mi cabeza contra el teclado, al final del todo ha resultado una experiencia divertida y enriquecedora. La necesidad de este programa surgió mientras estuve usando programas similares en Windows para jugar varios juegos que no brindaban soporte de controlador nativo. Aunque existían algunas alternativas en Linux, en realidad no había nada que me pareciera lo suficientemente bueno en términos de funcionalidad o control dentro del juego para disfrutar realmente de los juegos con los que quería jugar usando la emulación KB+M. QJoyPad era el principal programa que estuve usando en el pasado, aunque había envejecido mucho y no proporcionaba algunas funciones básicas que creía esenciales. El proyecto estaba muerto ya que no se había actualizado en varios años, así que decidí hacer el mío propio. Desde entonces, he tratado de averiguar qué hacen bien los otros programas y luego mejorarlo. También descubrí algunos trucos geniales por el camino y aprendí más de lo que realmente quería saber sobre cómo se implementan los controles nativos para mandos en algunos juegos . Aunque definitivamente hay áreas en las que este programa podría mejorar, creo que ofrece la mejor experiencia de control dentro del juego para jugar juegos más antiguos y algunos más nuevos que no brindan soporte de controlador nativo. El desarrollo de este programa ya no es una prioridad tan alta para mí. Esto se debe principalmente al hecho de que Steam Controller funciona bastante bien para la tarea de jugar juegos de PC en comparación con el uso de un controlador Xbox 360. Sin embargo, parece que todavía hay alguna razón para que este programa exista por un tiempo. --- El 24 de mayo de 2016 este proyecto se movió a https://github.com/AntiMicro/antimicro. Además, la gestión del proyecto ha pasado de Travis (Ryochan7) a la organización de AntiMicro debido a que Travis tiene otros intereses y prioridades. A continuación, desde 2018 juliagoda ha continuado el proyecto en el proyecto antimicroX. Posteriormente el proyecto se ha movido una vez más a https://github.com/AntiMicroX/antimicrox y se continua su mantenimiento desde la organización AntiMicroX creada por pktiuk. Copyright: 2013 - 2022 Copyright: 2013 - 2022 Info Información <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> Changelog Registro de cambios Credits Créditos AntiMicroX AntiMicroX About Development Acerca del desarrollo License Licencia Program Version %1 Versión del programa %1 Compiled from packaging: %1 Compilado desde el empaquetado: %1 Program Compiled on %1 at %2 Programa compilado el %1 a las %2 Built Against SDL %1 Construído contra SDL %1 Running With SDL %1 Ejecutándose con SDL %1 Using Qt %1 Usando Qt %1 Using Event Handler: %1 Usando gestor de eventos: %1 AddEditAutoProfileDialog Auto Profile Dialog Diálogo de Perfil Automático Pro&file: Per&fil: Browse Navegar Window: Ventana: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Seleccione la ventana. Pulse en la aplicación correspondiente y se completará la ruta al fichero de la aplicación en el formulario. Detect Window Properties Detectar propiedades de la ventana &Class: &Clase: T&itle: T&ítulo: set partial title es título parcial Application: Aplicación: Select Seleccionar De&vices: Dis&positivos: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Seleccionar este perfil para que se cargue por defecto para el dispositivo especificado. La selección se usará en lugar de la opción de perfil pror defecto. Set as Default for Controller Establecer como predeterminado para el controlador A different profile is already selected as the default for this device. Ya se ha seleccionado un perfil diferente como predeterminado para este dispositivo. Current (%1) Actual (%1) Open Config Abrir configuración Select Program Seleccionar programa Programs (*.exe) Programas (*.exe) Please use the main default profile selection. Utilice la selección principal de perfil predeterminado. Main Profile Perfil principal Already selected Ya seleccionado Chosen Profile Perfil elegido The selection will be used instead of the all default profile option. La selección se usará en vez de la opción de todo perfil predeterminado. Please select a window by using the mouse. Press Escape if you want to cancel. Seleccione una ventana utilizando el ratón. Pulse Escape si desea cancelar. Capture Application Window Captura de Ventana de Aplicación Could not obtain information for the selected window. No es posible obtener información de la ventana seleccionada. Application Capture Failed Fallo de Captura de Aplicación Profile file path is invalid. La ruta del archivo del perfil no es válida. No window matching property was specified. No se ha especificado propiedad de asociación de ventana. Program path is invalid or not executable. La ruta al programa no es válida o no es ejecutable. File is not an .exe file. El archivo no es un .exe. No window matching property was selected. No se ha seleccionado propiedad de asociación de ventana. AdvanceButtonDialog Advanced Avanzado Assignments Asignaciones Toggle Alternar Turbo Turbo Set Selector Selector de conjunto Blank or KB/M Vacio o KB/M Hold Mantener Pause Pausar Cycle Ciclo Distance Distancia Insert Insertar Delete Borrar Clear All Limpiar todo Time: Duración: 0.01s 0.01s 0s 0s Insert a pause that occurs in between key presses. Insertar una pausa entre pulsaciones de teclas. Release Soltar Insert a new blank slot. Insertar una nueva ranura en blanco. Join Unir Split Separar Delete a slot. Borrar una ranura. Clear all currently assigned slots. Limpiar todas las ranuras asignadas actualmente. Specify the duration of an inserted Pause or Hold slot. Especificar la duración de una ranura insertada de Pausa o Mantener. 0m 0m &Mouse Speed Mod: &Mod. velocidad del ratón: Specify the range past an axis dead zone in which a sequence of actions will execute. Especificar el rango pasada una zona muerta del eje en el que se ejecutará una secuencia de acciones. Distance: Distancia: % % Mouse Mod Mod. ratón Press Time Duración de presionado Delay Retardo Execute Ejecutar Load Cargar Set Change Cambiar conjunto Text Entry Entrada de texto Placeholder Marcador de posición 0 0 Set the percentage that mouse speeds will be modified by. Establecer el porcentaje de modificación de velocidad del ratón. Auto Reset Cycle After Auto-restablecer Ciclo Tras seconds segundos Executable: Ejecutable: ... ... Arguments: Argumentos: Enabled Habilitado Mode: Modo: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>Normal:. Pulsar y soltar repetidamente un botón a la tasa elegida </p><p> Gradiente: Modificar el retraso de pulsación y liberación de un botón según cuán lejos se ha movido un eje. La tasa seguirá siendo la misma.</p><p>Pulso:. Modifica cuántas veces por segundo se presiona y libera un botón. El retardo del botón seguirá siendo el mismo.</p></body></html> Normal Normal Gradient Gradiente Pulse Pulso Delay: Retardo: 0.10s 0.10s Rate: Tasa: 10.0/s 10.0/s Disabled Deshabilitado Select Set 1 One Way Seleccionar Conjunto 1 Unidireccional Select Set 1 Two Way Seleccionar Conjunto 1 Bidireccional Select Set 1 While Held Seleccionar Conjunto 1 Mientras se Mantiene Select Set 2 One Way Seleccionar Conjunto 2 Unidireccional Select Set 2 Two Way Seleccionar Conjunto 2 Bidireccional Select Set 2 While Held Seleccionar Conjunto 2 Mientras se Mantiene Select Set 3 One Way Seleccionar Conjunto 3 Unidireccional Select Set 3 Two Way Seleccionar Conjunto 3 Bidireccional Select Set 3 While Held Seleccionar Conjunto 3 Mientras se Mantiene Select Set 4 One Way Seleccionar Conjunto 4 Unidireccional Select Set 4 Two Way Seleccionar Conjunto 4 Bidireccional Select Set 4 While Held Seleccionar Conjunto 4 Mientras se Mantiene Select Set 5 One Way Seleccionar Conjunto 5 Unidireccional Select Set 5 Two Way Seleccionar Conjunto 5 Bidireccional Select Set 5 While Held Seleccionar Conjunto 5 Mientras se Mantiene Select Set 6 One Way Seleccionar Conjunto 6 Unidireccional Select Set 6 Two Way Seleccionar Conjunto 6 Bidireccional Select Set 6 While Held Seleccionar Conjunto 6 Mientras se Mantiene Select Set 7 One Way Seleccionar Conjunto 7 Unidireccional Select Set 7 Two Way Seleccionar Conjunto 7 Bidireccional Select Set 7 While Held Seleccionar Conjunto 7 Mientras se Mantiene Select Set 8 One Way Seleccionar Conjunto 8 Unidireccional Select Set 8 Two Way Seleccionar Conjunto 8 Bidireccional Select Set 8 While Held Seleccionar Conjunto 8 Mientras se Mantiene [NO KEY] [SIN TECLA] sec. seg. /sec. /seg. Not checked slots Sin ranuras marcadas To delete slots, you need to select at least one Para borrar ranuras debes seleccionar una como mínimo To insert slots, you need to select at least one Para insertar ranuras debes seleccionar una como mínimo Unknown current slot Ranura actual desconocida Click on chosen slots before joining them Haz clic en las ranuras elegidas antes de unirlas Not enough slots Sin ranuras suficientes It's impossible to join slots. Add at least one other slot. No es posible unir ranuras. Añade al menos otra ranura más. Not selected slots Sin ranuras seleccionadas It's impossible to join slots. Select at least two slots before joining them No es posible unir ranuras. Selecciona al menos dos ranuras antes de unirlas Only keyboard slots Solo ranuras de teclado It's only possible to join simple and mix keyboard slots Solo se pueden unir ranuras de teclado simples y mixtas It's impossible to split slots. Add at least one other slot. No es posible separar ranuras. Añade al menos otra ranura. Not selected slot Sin ranura seleccionada Select your slot before splitting. Selecciona la ranura antes de separar. Too many mix slots Demasiadas ranuras mixtas Select one mix slot. Selecciona una ranura mixta. Only mix slots Solo ranuras mixtas It's only possible to split mix slot. Solo se puede separar una ranura mixta. Empty execution path Ruta de ejecución vacía Line for execution file path is empty. Fill the first line before you are going to add a slot. La línea de ruta al archivo de ejecución está vacía. Rellene la primera línea antes de añadir una ranura. File doesn't exist El archivo no existe There is no such file locally, that could be executed. Check the file on your system No existe tal archivo local que se pueda ejecutar. Comprueba el archivo en tu sistema de archivos Set %1 Configurar %1 Select Set %1 Seleccionar conjunto %1 One Way Unidireccional Two Way Bidireccional While Held Mientras se mantiene Choose Executable Escoger ejecutable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Se ejecutarán las ranuras tras una acción de ciclo en la siguiente pulsación de un botón. Es posible añadir múltiples ciclos para crear particiones en una secuencia. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Retrasa el momento en que se activará la siguiente ranura el tiempo especificado. Las ranuras que se activen tras el retardo permanecerán activas una vez se supere este tiempo. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Acción de Distancia especifica que las ranuras siguientes solo se ejecutarán cuando un eje se mueva cierta distancia pasada la zona muerta asignada. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Insertar una acción de retención. Las ranuras tras la acción solo se ejecutarán si el botón se mantiene más allá del intervalo especificado. Chose a profile to load when this slot is activated. Elija un perfil a cargar cuando se active esta ranura. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. El Mod. de Acción del Ratón modificará todos los ajustes de velocidad del ratón un porcentaje especificado mientras la acción se está procesando. Esto puede resultar útil para ralentizar el ratón para francotiradores. Specify the time that keys past this slot should be held down. Especifica la duración que las teclas deben mantenerse pulsadas tras esta ranura. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Insertar una acción de liberación. Las ranuras después de la acción solo se ejecutarán tras liberar un botón si éste se presionó más allá del intervalo especificado. Change to selected set once slot is activated. Cambiar al conjunto seleccionado una vez se active la ranura. Full string will be typed when a slot is activated. Se tecleará la cadena completa al activarse la ranura. Execute program when slot is activated. Ejecutar un programa cuando se active la ranura. Choose Profile Elegir perfil Config Files (*.amgp *.xml) Archivos de config. (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Asignación de Palanca/Mando Sticks Palancas DPads Crucetas Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. Nota: esta ventana está destinada a la compatibilidad con versiones anteriores de perfiles creados antes de antimicro 2.0. Desde la versión 2.0, se prefiere el uso de la ventana Mapeo del controlador de juego. %1 (Joystick %2) %1 (Mando %2) Stick 1 Palanca 1 Enabled Habilitar Assign Asignar X Axis: Eje X: Y Axis: Eje Y: Stick 2 Palanca 2 Number of Physical DPads: %1 Numero de crucetas físicas: %1 Virtual DPad 1 Cruceta virtual 1 Up: Arriba: Down: Abajo: Left: Izquierda: Right: Derecha: Axis %1 Eje %1 Axis %1 - Eje %1 - Axis %1 + Eje %1 + Button %1 Botón %1 Move stick 1 along the X axis Mueva la palanca 1 a lo largo del eje X Move stick 1 along the Y axis Mueva la palanca 1 a lo largo del eje Y Move stick 2 along the X axis Mueva la palanca 2 a lo largo del eje X Move stick 2 along the Y axis Mueva la palanca 2 a lo largo del eje Y Press a button or move an axis Presione un botón o mueva un eje AxisEditDialog Axis Ejes Mouse (Horizontal) Ratón (horizontal) Mouse (Inverted Horizontal) Ratón (horizontal invertido) Mouse (Vertical) Ratón (vertical) Mouse (Inverted Vertical) Ratón (vertical invertido) Arrows: Up | Down Flechas: Arriba | Abajo Arrows: Left | Right Flechas: Izquierda | Derecha Keys: W | S Teclas: W | S Keys: A | D Teclas: A | D NumPad: KP_8 | KP_2 Teclado num.: 8 | 2 NumPad: KP_4 | KP_6 Teclado num.: 4 | 6 None Ninguno Set the value to use as the limit for an axis. Useful for a worn out analog stick. Establece el valor a utilizar como límite para un eje. Útil para palancas analógicas desgastadas. Negative Half Throttle Mitad de aceleración negativa Positive Half Throttle Mitad de aceleración positiva Haptic Trigger: Disparador háptico: Name: Nombre: Specify the name of an axis. Especifica el nombre del eje. Mouse Settings Configuración del ratón Set the value of the dead zone for an axis. Establece el valor de la zona muerta para un eje. Presets: Preajustes: Dead Zone: Zona muerta: Max Zone: Zona máxima: [NO KEY] [SIN TECLA] Throttle setting that determines the behavior of how to interpret an axis hold or release. Ajuste del acelerador que determina el comportamiento de cómo interpretar la retención o liberación de un eje. Negative Throttle Aceleración negativa Normal Normal Positive Throttle Aceleración positiva Current Value: Valor actual: Set Configurar Set %1 Configurar %1 Left Mouse Button Botón izquierdo del ratón Right Mouse Button Botón derecho del ratón Click Pulse Rigid Rígido Rigid Gradient Degradado rígido Vibration Vibración ButtonEditDialog Dialog Diálogo To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Para realizar una nueva asignación, pulse cualquier tecla del teclado o haga clic en la pestaña Teclado o Ratón Placeholder Marcador de posición Toggle Alternar Enables a key press or release to only occur when a controller button is pressed. Permite que una tecla se presione o suelte solo cuando se presiona un botón del controlador. Enables rapid key presses and releases. Turbo controller. Permite presionar y soltar teclas rápidamente. Controlador turbo. Turbo Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Recuerda que no funcionará si no tienes el teclado conectado al ordenador o si no está integrado como en los ordenadores de sobremesa Attach the numeric keypad Colocar el teclado numérico Last keyboard/mouse button: Último botón del teclado/ratón: Slots Ranuras Na&me: No&mbre: Specify the name of a button. Especifique el nombre de un botón. Action: Acción: Specify the action that will be performed in game while this button is being used. Especifique la acción que se realizará en el juego mientras se utiliza este botón. Advanced Avanzado Choose your keyboard key Elija la tecla del teclado No button Sin botón Last button Último botón To change settings for last button, it must be at least one assignment from keyboard to gamepad Para cambiar la configuración del último botón, debe haber al menos una asignación del teclado al mando To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad Para cambiar la configuración de turbo para el último botón, debe haber al menos una asignación del teclado al mando No choice Sin elección Before you open window with advanced settings, you have to choice a key Antes de abrir la ventana con la configuración avanzada, debe elegir una tecla To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Para abrir el cuadro de diálogo avanzado es necesario asignar al menos un botón del teclado al mando Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad No se han podido borrar las ranuras para el botón porque no había ningún botón establecido desde el teclado para el mando. Asigne al menos un botón del teclado al mando As last gamepad button has been set Cómo se ha configurado el último botón del mando Index %1 Índice %1 Calibration Form Formulario Input to calibrate: Entra para calibrar: Steps Pasos Z Z TextLabel Etiqueta de texto X Eje X gain ganancia offset impresión offset Y Eje y Start calibration Comenzar calibración Close Cerrar Reset settings Restablecer configuración Save Guardar Calibration Calibración Gyroscope Giroscopio Accelerometer Acelerómetro Selected device doesn't have any inputs to calibrate. El dispositivo seleccionado no tiene entradas para calibrar. Calibration was not saved for the preset. Do you really want to continue? La calibración no se ha guardado para el preajuste. ¿Realmente desea continuar? Do you really want to reset calibration of current device? ¿Realmente desea restablecer la calibración del dispositivo actual? Accelerometer calibration sets the neutral controller orientation. La calibración del acelerómetro establece una orientación neutra del mando. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. La calibración del giroscopio corrige el desplazamiento del sensor. Esto evita el movimiento del cursor mientras el mando está en reposo. Calibration completed. Calibración completada. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Calibración de compensación completada. Haga clic en "Continuar calibración" para continuar con la calibración de ganancia. Hold the controller in the desired neutral position and press continue. Mantenga el mando en una posición neutra deseada y pulse continuar. Calibrating accelerometer Calibrando el acelerómetro Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Recogiendo datos del acelerómetro... Por favor, mantenga el mando quieto. Esto puede tardar hasta %1 segundos. Place the controller at rest, e.g. put it on the desk, and press continue. Coloque el mando en reposo, por ejemplo, sobre el escritorio, y pulse continuar. Calibrating gyroscope Calibrando el giroscopio Collecting gyroscope data... This can take up to %1 seconds. Recopilando datos del giroscopio... Esto puede tardar hasta %1 segundos. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Ahora mueve la palanca varias veces al máximo en diferentes direcciones y vuelve al centro. Esto puede llevar hasta %1 segundos. Calibrating stick Varilla de calibración Continue calibration Continuar con la calibración Now move the stick in full circles for several times. This can take up to %1 seconds. Ahora mueve la palanca en círculos completos durante varias veces. Esto puede llevar hasta %1 segundos. Calibration was saved for the preset. Do you really want to reset settings? Se ha guardado la calibración para el preajuste. ¿Realmente desea restablecer la configuración? CapturedWindowInfoDialog Captured Window Properties Propiedades de Captura de Ventana Information About Window Información acerca de la ventana Class: Clase: TextLabel Etiqueta de texto Title: Título: Path: Ruta: Match By Properties Asignar según propiedades Class Clase Title Título Path Ruta Full Path Ruta completa File Name Nombre de archivo DPadContextMenu Mouse (Normal) Ratón (normal) Mouse (Inverted Horizontal) Ratón (horizontal invertido) Mouse (Inverted Vertical) Ratón (vertical invertido) Mouse (Inverted Horizontal + Vertical) Ratón (horizontal+vertical invertido) Arrows Flechas Keys: W | A | S | D Teclas: W | A | S | D NumPad Teclado numérico None Ninguna Standard Estándar Eight Way Ocho vías 4 Way Cardinal 4 vías cardinal 4 Way Diagonal 4 vías diagonal Mouse Settings Configuracion de ratón DPadEditDialog Dialog Diálogo Presets: Preajustes: Mouse (Normal) Ratón (normal) Mouse (Inverted Horizontal) Ratón (horizontal invertido) Mouse (Inverted Vertical) Ratón (vertical invertido) Mouse (Inverted Horizontal + Vertical) Ratón (horizontal+vertical invertido) Arrows Flechas Keys: W | A | S | D Teclas: W | A | S | D NumPad Teclado numérico None Ninguno Dpad Mode: Modo de cruceta: &Name: &Nombre: 4 Way Cardinal 4 vías cardinal 4 Way Diagonal 4 vías diagonal DPad Delay: Retardo de cruceta: Time lapsed before a direction change is taken into effect. Tiempo transcurrido antes de que un cambio de dirección tenga efecto. s s Specify the name of a dpad. Especifique un nombre para la cruceta. Mouse Settings Configuración del ratón Standard Estándar Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Estándar: cruceta de 8 regiones con dos botones de dirección activos cuando la cruceta está en una región diagonal. Ocho vías: cruceta de 8 regiones con cada dirección con su propio botón dedicado. Solo un botón está activo en en cada momento. Útil para juegos tipo "rogue". Cardinal de 4 vías: cruceta de 4 regiones con regiones correspondientes a los puntos cardinales de la cruceta. Útil para menús. Diagonal de 4 vías: cruceta de 4 regiones con cada región correspondiente a una zona diagonal. Eight Way Ocho vías Set Configurar Set %1 Configurar %1 EditAllDefaultAutoProfileDialog Default Profile Perfil por defecto Profile: Perfil: Browse Navegar Open Config Abrir configuración Profile file path is invalid. La ruta al archivo de perfil no es válida. ExtraProfileSettingsDialog Extra Profile Settings Configuración extra del perfil Key Press Time: Tiempo de presionado de tecla: 0.00 ms 0.00 ms Profile Name: Nombre del perfil: s s GameController Game Controller Controlador de juego GameControllerDPad DPad Cruceta GameControllerMappingDialog Game Controller Mapping Asignación de Controles de Juego <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> <html><head/><body><p>antimicrox hace uso de la <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> que ofrece SDL 2 para abstraer mandos variados en un estándar unificado. Para poder asignar un botón, resalte abajo la casilla de asignación de la fila del botón correspondiente. Entonces puede pulsar un botón o mover un eje en su mando y la casilla se actualizará con el botón o eje físico que se usará.</p><p>antimicrox usará la asignación que especifique para guardar una cadena de asignación que se cargará en SDL.</p></body></html> A A B B X X Y Y Back Atrás Start Comenzar Guide Guía Left Shoulder Hombro izquierdo Right Shoulder Hombro derecho Left Stick Click Clic palanca izquierda Right Stick Click Clic palanca derecha Left Stick X Palanca izquierda X Left Stick Y Palanca izquierda Y Right Stick X Palanca derecha X Right Stick Y Palanca derecha Y Left Trigger Gatillo izquierdo Right Trigger Gatillo derecho DPad Up Cruceta arriba DPad Left Cruceta izquierda DPad Down Cruceta abajo DPad Right Cruceta derecha Mapping Asignación SDL 2 Game Controller Mapping String Cadena SDL 2 de asignación del controlador de juegos Last Axis Event: Último evento de eje: Current Axis Detection Dead Zone: Detección de zona muerta del eje actual: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Asignaciones del controlador de juegos (%1) (#%2) Discard Controller Mapping? ¿Descartar Asignaciones del Controlador? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. ¿Descartar asignaciones para este controlador? Si lo descarta, el controlador volverá a comportarse como un mando una vez actualice todos los mandos. GameControllerSet Back Atrás Guide Guía Start Comenzar LS Click Clic PI RS Click Clic PD L Shoulder Hombro I R Shoulder Hombro D L Trigger Gatillo I R Trigger Gatillo D GameControllerTrigger Trigger Gatillo JoyAccelerometerButton Up Subir Down Bajar Left A la izquierda Right A la derecha Shock Golpe JoyAccelerometerSensor Accelerometer Acelerómetro JoyAxis Axis Eje JoyAxisButton Negative Negativo Positive Positivo Unknown Desconocido Button Botón JoyAxisContextMenu Mouse (Horizontal) Ratón (horizontal) Mouse (Inverted Horizontal) Ratón (horizontal invertido) Mouse (Vertical) Ratón (vertical) Mouse (Inverted Vertical) Ratón (vertical invertido) Arrows: Up | Down Flechas: Arriba | Abajo Arrows: Left | Right Flechas: Izquierda | Derecha Keys: W | S Teclas: W | S Keys: A | D Teclas: A | D NumPad: KP_8 | KP_2 Teclado num.: 8 | 2 NumPad: KP_4 | KP_6 Teclado num.: 4 | 6 None Ninguna Mouse Settings Configuracion de ratón Left Mouse Button Botón izquierdo del ratón Right Mouse Button Botón derecho del ratón JoyButton Processing turbo for #%1 - %2 Procesando turbo para #%1 - %2 Finishing turbo for button #%1 - %2 Finalizando turbo para botón #%1 - %2 Distance change for button #%1 - %2 Cambio de distancia para botón #%1 - %2 Button Botón [NO KEY] [SIN TECLA] [Set %1 1W] [Establecer %1 UD] [Set %1 2W] [Establecer %1 BD] [Set %1 WH] [Establecer %1 MM] JoyButtonContextMenu Toggle Alternar Turbo Turbo Clear Limpiar Set Select Selección de conjunto Disabled Deshabilitado Set %1 Configurar %1 Set %1 1W Establecer %1 UD Set %1 2W Establecer %1 BD Set %1 WH Establecer %1 MM JoyButtonSlot Mouse Ratón Up Arriba Down Abajo Left Izquierda Right Derecha LB BI MB BC RB BD Pause Pausa Hold Mantener Cycle Ciclo Distance Distancia Release Soltar Mouse Mod Mod. ratón Press Time Tiempo de presionado Delay Retardo Load %1 Cargar %1 Set Change %1 Cambiar conjunto %1 [Text] %1 [Texto] %1 [Exec] %1 [Ejec] %1 [NO KEY] [SIN TECLA] JoyControlStick Stick Palanca JoyControlStickButton Up Arriba Down Abajo Left Izquierda Right Derecha Button Botón JoyControlStickContextMenu Mouse (Normal) Ratón (normal) Mouse (Inverted Horizontal) Ratón (horizontal invertido) Mouse (Inverted Vertical) Ratón (vertical invertido) Mouse (Inverted Horizontal + Vertical) Ratón (horizontal+vertical invertido) Arrows Flechas Keys: W | A | S | D Teclas: W | A | S | D NumPad Teclado numérico None Ninguno Standard Estándar Eight Way Ocho vías 4 Way Cardinal 4 vías cardinal 4 Way Diagonal 4 vías diagonal Mouse Settings Configuracion del ratón JoyControlStickEditDialog Dialog Diálogo X: X: 0 0 Y: Y: Distance: Distancia: Presets: Preajustes: Mouse (Normal) Ratón (normal) Mouse (Inverted Horizontal) Ratón (horizontal invertido) Mouse (Inverted Vertical) Ratón (vertical invertido) Mouse (Inverted Horizontal + Vertical) Ratón (horizontal+vertical invertido) Arrows Flechas Keys: W | A | S | D Teclas: W | A | S | D NumPad Teclado numérico None Ninguno Stick Mode: Modo de palanca: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Estándar: palanca de 8 regiones con dos botones de dirección activos cuando la palanca está en una región diagonal. Ocho vías: palanca de 8 regiones con cada dirección con su propio botón dedicado. Solo un botón está activo en en cada momento. Útil para juegos tipo "rogue". Cardinal de 4 vías: palanca de 4 regiones con regiones correspondientes a los puntos cardinales del dpad. Útil para menús. Diagonal de 4 vías: palanca de 4 regiones con cada región correspondiente a una zona diagonal. 4 Way Cardinal 4 vías cardinal 4 Way Diagonal 4 vías diagonal Modifier Zone: Modificador de Zona: Dead zone value to use for an analog stick. Valor de zona muerta para una palanca analógica. Value when an analog stick is considered moved 100%. Valor para considerar que una palanca analógica se ha movido al 100%. The area (in degrees) that each diagonal region occupies. El área (en grados) que ocupa cada región diagonal. Square Stick: Palanca cuadrangular: Percentage to modify a square stick coordinates to confine values to a circle Porcentaje para modificar las coordenadas de una palanca cuadrangular para confinar los valores en un círculo % % Stick Delay: Retardo de la palanca: Time lapsed before a direction change is taken into effect. Tiempo transcurrido antes de que un cambio de dirección tenga efecto. s s Modifier: Modificador: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Botón de edición que estará activo mientras la palanca esté activa. Este botón es útil para asignar zonas con teclas modificadoras que se pueden usar para asignar funcionalidad andar/correr a una palanca analógica. PushButton Pulse un botón Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Umbral a partir del cual se activa el botón del modificador. Este botón es útil para asignar zonas con teclas modificadoras que se pueden utilizar para asignar la funcionalidad de caminar/correr a un stick analógico. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Define si los botones modificadores se activan cuando el stick está dentro o fuera del valor umbral. Este botón es útil para asignar zonas con teclas modificadoras que se pueden utilizar para asignar a un stick analógico. Invert Modifier Zone Invertir la zona modificadora Na&me: Name: No&mbre: Specify the name of an analog stick. Especifique un nombre para la palanca analogica. Mouse Settings Configuración del ratón Standard Estándar Bearing: Ángulo: % Safe Zone: % Zona segura: Eight Way Ocho vías Dead Zone: Zona muerta: Max Zone: Zona máxima: Diagonal Range: Rango diagonal: Set Configurar Set %1 Configurar %1 JoyControlStickModifierButton Modifier Modificador JoyDPad DPad Cruceta JoyDPadButton Up Arriba Down Abajo Left Izquierda Right Derecha Button Botón JoyGyroscopeButton Pitch Up Aumentar Pitch Down Disminuir Yaw Left Giro a la izquierda Yaw Right Giro a la derecha Roll Left Giré a la izquierda Roll Right Giré a la izquierda JoyGyroscopeSensor Gyroscope Giroscopio JoySensorButton Button Pulsador JoySensorContextMenu Mouse Settings Ajustes del ratón JoySensorEditDialog Dialog Diálogo 0 0 Acceleration (m/s^2): Aceleración (m/s^2): Pitch (°): Inclinación (°): Roll (°): Balanceo (°): % Safe Zone: % de la zona segura: Presets: Preajustes: Dead Zone: Zona muerta: Dead zone value to use for an analog sensor. Valor de la zona muerta a utilizar para un sensor analógico. Max Zone: Zona máxima: Value when an analog sensor is considered moved 100%. Valor cuando un sensor analógico se considera movido hasta el 100%. Diagonal Range: Rango en diagonal: The area (in degrees) that each diagonal region occupies. El área (en grados) que ocupa cada región en diagonal. Sensor Delay: Retraso del sensor: Time lapsed before a direction change is taken into effect. Tiempo transcurrido antes de que se haga efectivo un cambio de dirección. s s Na&me: Na&me: Specify the name of an analog sensor. Especifique el nombre de un sensor analógico. Mouse Settings Configuración del ratón Roll (°/s) Balanceo (°/s) Pitch (°/s) Inclinación (°/s) Yaw (°/s) Viraje (°/s) Set Fijar Set %1 Fijar %1 JoySensorPreset None Ninguno Mouse (Normal) Ratón (normal) Mouse (Inverted Horizontal) Ratón (horizontal invertido) Mouse (Inverted Vertical) Ratón (vertical invertido) Mouse (Inverted Horizontal + Vertical) Ratón (horizontal+vertical invertido) Arrows Flechas Keys: W | A | S | D Teclas: W | A | S | D NumPad Teclado numérico JoyTabWidget <New> <Nuevo> Battery level of controller Nivel de batería del mando Remove Eliminar Remove configuration from recent list. Eliminar la configuración de la lista de recientes. Load Cargar Load configuration file. Carga un fichero de configuración. Save Guardar Save changes to configuration file. Guarda los cambios en un fichero de configuración. Save As Guardar como Save changes to a new configuration file. Guarda los cambios en un nuevo fichero de configuración. Sets Conjuntos Copy from Set Copiar desde conjunto Settings Configuración Set 1 Conjunto 1 Set 2 Conjunto 2 Set 3 Conjunto 3 Set 4 Conjunto 4 Set 5 Conjunto 5 Set 6 Conjunto 6 Set 7 Conjunto 7 Set 8 Conjunto 8 Stick/Pad Assign Asignación de palanca/mando Controller Mapping Asignaciones del controlador Quick Set Configuración rápida Names Nombres Toggle button name displaying. Alternar mostrar nombre de botón. Pref Perfil Change global profile settings. Cambia la configuración de perfil global. Reset Restablecer Revert changes to the configuration. Reload configuration file. Revertir los cambios en la configuración. Recarga el fichero de configuración. Open Config Abrir configuración Config Files (*.amgp *.xml) Archivos de configuración (*.amgp *.xml) Config File (*.%1.amgp) Archivo de configuración (*.%1.amgp) Do you really want to reset buttons settings for joystick? ¿Realmente desea restablecer la configuración del botones del mando? Save Profile Changes? ¿Guardar Cambios del Perfil? Changes to the new profile have not been saved. Would you like to save or discard the current profile? No se han guardado los cambios del nuevo perfil. ¿Desea guardar o descartar el perfil actual? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? No se han guardado los cambios del perfil "%1". ¿Desea guardar o descartar los cambios del perfil actual? Sticks Palancas Sensors Sensores DPads Crucetas No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. No se ha asignado ningún botón. Use Configuración Rápida para asignar teclas a botons o desactive ocultar botones vacíos. Set %1: %2 Conjunto %1: %2 Set %1 Conjunto %1 Copy Set Assignments Copiar Conjuntos de Asignaciones Are you sure you want to copy the assignments and device properties from %1? ¿Está seguro de querer copiar las asignaciones y propiedades del dispositivo desde %1? Save Config Guardar configuración Set Conjunto Joystick Joystick Palanca JoystickStatusWindow Properties Propiedades Details Detalles Name: Nombre: %1 %1 Number: Número: Axes: Ejes: Buttons: Botones: Hats: Sombreros: Sensors: Sensores: Battery: Batería: Unknown Desconocido GUID: GUID: Game Controller: Controlador de juego: Axes Ejes Buttons Botones Hats Sombreros Sensors Sensores %1 (#%2) Properties Propiedades de %1 (#%2) Empty Vacio Low Bajo Medium Medio Full Completo Wired Cable Different: %1 Diferente: %1 Accelerometer + Gyroscope Acelerómetro y giroscopio Accelerometer Acelerómetro Gyroscope Giroscopio None Ninguno Axis %1 Eje %1 Hat %1 Sombrero %1 No No Yes MainSettingsDialog Edit Settings Editar Configuración General General Controller Mappings Asignación de controles Language Idioma Auto Profile Perfil automático Mouse Ratón Advanced Avanzado Pro&file Directory: Directorio de per&files: <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Especifique el directorio que el programa debe utilizar por defecto en los diálogos de archivo cuando se carga o guarda un nuevo perfil.</p></body></html> Recent Profile Count: Cantidad de perfiles recientes: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Número de perfiles que se colocarán en la lista de perfiles recientes. 0 provocará que el programa no limite el número de perfiles a mostrar.</p></body></html> Gamepad Poll Rate: Tasa de sondeo del mando: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Cambiar la tasa de sondeo que el programa utiliza para descubrir nuevos eventos en los mandos. El valor predeterminado es de 10 ms. La reducción del valor de tasa de sondeo podría causar que la aplicación use más energía de la CPU así que por favor pruebe la configuración que utilice antes de usar AntimicroX de forma desatendida. Hide main window when the main window close button is clicked instead of quitting the program. Ocultar la ventana principal cuando se hace clic en el botón de cerrar la ventana en lugar de salir del programa. Close To Tray Cerrar en la bandeja del sistema Have Windows start AntiMicroX at system startup. Hacer que Windows inicie AntimicroX junto con el sistema. Launch At Windows Startup Iniciar junto con Windows Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Mostrar perfiles más recientes de todos los mandos como una única lista en el menú de la bandeja. Usa submenús de forma predeterminada. Single Profile List in Tray Lista única de perfiles en la bandeja de sistema Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Hacer que el programa minimize a la barra de tareas. Por defecto, el programa se minimiza en la bandeja del sistema si está disponible. Minimize to Taskbar Minimizar en la barra de tareas This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Esta opción hará que el programa oculte todos los botones que no tienen ranuras asignadas. Deberá usarse la ventana de diálogo de Configuración Rápida para que aparezca el diálogo de edición de los botones del mando. Hide Empty Buttons Ocultar botones vacíos When the program is launched, open the last known profile that was opened during the previous session. Cuando el programa esté en marcha, abrir el último perfil conocido que se abrió durante la sesión anterior. Auto Load Last Opened Profile Autocargar el último perfil abierto Only show the system tray icon when the program first launches. Mostrar únicamente el icono en la bandeja de sistema cuando se lance el programa inicialmente. Launch in Tray Lanzar en la bandeja del sistema Associate .amgp files with AntiMicroX in Windows Explorer. Asociar archivos .amgp con AntiMicroX en Windows Explorer. Associate Profiles Asociar perfiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Recuerde que no funcionará si no tiene ese tipo de teclado conectado a su ordenaor o no está incluído como en el teclado de los PCs Attach the numeric keypad Conectar al teclado numérico Show low battery notification Mostrar notificación de batería baja Show empty battery notification Mostrar notificación sin batería Key Repeat Repetición de tecla Active keys will be repeatedly pressed when this option is enabled. Las teclas activadas se pulsarán repetidamente cuando esta opción esté activa. Enable Habilitar Specifies how much time should elapse before key repeating begins. Especifica cuánto tiempo debe transcurrir antes de que comience a repetirse la tecla. Specifies how many times key presses will be performed per seconds. Especifica cuántas veces se por segundo se llevarán a cabo las pulsaciones de tecla. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntimicroX ha sido traducido a muchos idiomas diferentes por los contribuyentes. Por defecto, el programa elegirá una traducción apropiada basada en la configuración regional de su sistema. Sin embargo, puede hacer que AntimicroX cargue una traducción diferente en función del idioma que elija en la lista siguiente.</p></body></html> Português do Brasil Portugués de Brasil Français Francés Deutsch Alemán Italiano Italiano 日本語 Japonés Русский Ruso српски / srpski Serbio 简体中文 Chino simplificado Español Español українська Ucraniano Polski Polaco History Si&ze: Tamaño del &historial: Weight Modi&fier: Modi&ficador de peso: Log File: Archivo de registro: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> <html><head/><body><p><span style=" font-style:italic;">Nota: si no especifica archivo de registro se imprimirá en la salida de la consola</span></p></body></html> Log Level: Nivel de registro: None Ninguno Error Error Warning Advertencia Info Información Verbose Verboso Debug Depuración Note: To see the change of log level in console output (not in log file), application restart is required Nota: para ver cambios en el nivel de registro en la salida por consola (no en el archivo de registro) se necesita reiniciar la aplicación Reset Restablecer Class Clase Title Título Program Programa Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Desactiva la configuración de Windows "mejorar precisión del puntero" mientras AntimicroX se está ejecutando. Desactivar "mejorar precisión del puntero" permitirá que el movimiento del ratón dentro de AntimicroX sea más preciso. Disable Enhance Pointer Precision Desactivar la precisión del puntero mejorada Smoothing Suavizado Refresh Rate: Frecuencia de actualizacion: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. La frecuencia de actualización es la cantidad de tiempo que transcurrirá entre los eventos del ratón. Por favor tenga cuidado cuando edite este ajuste ya que esto hará que el programa utilice más potencia de la CPU. Un valor demasiado bajo puede causar inestabilidad en el sistema. Por favor, pruebe la configuración antes de usarlo de forma desatendida. Spring Muelle Screen: Pantalla: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Utilizar la pantalla especificada para el modo muelle. En Linux, el valor por defecto es la pantalla principal. En Windows, el valor por defecto es utilizar todas las pantallas disponibles. Accel Numerator: Numerador de aceleración: 0 0 Accel Denominator: Denominador de aceleración: Accel Threshold: Límite de aceleración: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Si los valores de aceleración para el ratón virtual han sido cambiados por un proceso diferente, particularmente cuando se cierra un juego antiguo, entonces es posible que desee restablecer los valores de aceleración utilizados por el ratón virtual. Reset Acceleration Restablecer aceleración Delay: Retardo: ms ms Rate: Tasa: times/s veces/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. Abajo hay una lista de las asignaciones personalizadas que se han guardado. Puede usar la tabla siguiente para eliminar las asignaciones o deshabilitarlas temporalmente. También puede desactivar las asignaciones que se incluyen con SDL; sólo tiene que insertar una nueva fila con el GUID de la palanca de mando correspondiente y marcar desactivado. Los ajustes no tendrán efecto hasta que recargue todos los mandos o desenchufe ese mando en particular. GUID GUID Mapping String Cadena de asignación Disable? ¿Desactivar? Delete Eliminar Default Por defecto English Inglés Active Activo Devices: Dispositivos: All Todos Device Dispositivo Profile Perfil Default? ¿Por defecto? Add Añadir Edit Editar AutoProfile (disabled in Wayland) AutoPerfil (deshabilitado en Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Además, los usuarios de Windows que deseen utilizar un valor bajo pueden tambien marcar "desactivar mejorar precisión del puntero" en caso de que no haya desactivado la opción en Windows. Select Default Profile Directory Seleccionar el Directorio de Perfil por defecto Are you sure you want to delete the profile? ¿Está seguro de querer borrar el perfil? Save Log File As Guardar archivo de registro como Log Files (*.log) Archivos de registro (*.log) Do you really want to reset setting? ¿Realmente desea restablecer la configuración? Would you like to reset mappings too? ¿Desea restablecer también las asignaciones? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu No se ha encontrado ningún mando Conecte un mando y elija la opción "Actualizar mandos" en el menu principal If events are not seen by a game, please click here to run this application as Administrator. Si un juego no es capaz de ver los eventos, haga clic aquí para ejecutar esta aplicación como administrador. Update Button Botón de actualización &App &Aplicación &Options &Opciones He&lp A&yuda &Quit Sa&lir Ctrl+Q Ctrl+Q &Update Joysticks Act&ualizar mandos Ctrl+U Ctrl+U &Hide O&cultar Ctrl+H Ctrl+H &About Acerca &de Ctrl+A Ctrl+A About &Qt Acerca de &Qt Ctrl+T Ctrl+T &Properties &Propiedades Ctrl+P Ctrl+P &Key Checker Verificador de &teclas Ctrl+K Ctrl+K &GitHub Page Página de &GitHub Ctrl+G Ctrl+G S&ettings Con&figuración Ctrl+S Ctrl+S &Stick/Pad Assign Asignar &palanca/mando Ctrl+X Ctrl+X &Wiki &Wiki Ctrl+W Ctrl+W &Issues &Incidencias Ctrl+I Ctrl+I &Calibration &Calibración Ctrl+C Ctrl+C Home Page Página principal (%1) (%1) Open File Abrir archivo Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. ¿Está seguro de querer ejecutar este programa como administrador? Algunos juegos se ejecutan como administrador, lo cual provoca que los eventos que genera antimicro no se puedan usar en ellos salvo que antimicro se ejecute también como administrador. Esto se debe a problemas de permisos causados por el Control de Cuentas de Usuario (UAC) de Windows Vista y posteriores. %1 battery Batería %1 Battery level is less than %1 El nivel de la batería es menor que %1 Device number: %1 Device name: %2 Número de dispositivo: %1 Nombre de dispositivo: %2 Update to %1 available Actualización a %1 disponible Reading old profile Leyendo perfil antiguo This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 El perfil usa los números de GUID de los controladores. ¿Desea cambiar los números de GUID a UniqueID en este archivo para su uso en controladores idénticos? Este tipo de archivos antiguos no se puede cargar en antimicrox desde la versión 2.25 &Restore &Restaurar Calibration couldn't be opened No se puede abrir la calibración You must connect at least one controller to open the window Debe conectar al menos un controlador para abrir la ventana Run as Administrator? ¿Ejecutar como administrador? Failed to elevate program Fallo al elevar el programa Failed to restart this program as the Administrator Fallo al reiniciar este programa como administrador MouseAxisSettingsDialog Mouse Settings - Configuración del Ratón - Set %1 Configurar %1 MouseButtonSettingsDialog Mouse Settings - Configuración del Ratón - Set %1 Configurar %1 MouseControlStickSettingsDialog Mouse Settings Configuración del Ratón Set %1 Configurar %1 MouseDPadSettingsDialog Mouse Settings Configuración del Ratón Set %1 Configurar %1 MouseSensorSettingsDialog Mouse Settings Configuración del ratón Set %1 Establecer %1 MouseSettingsDialog Mouse Settings Configuración del Ratón Mouse Mode: Modo del ratón: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. El modo cursor se usa para mover el cursor del ratón a lo largo de la pantalla relativamente a su posición actual dependiendo de cuánto muevas un eje o si se pulsa un botón. El modo muelle se usa para mover el cursor del ratón desde el centro de la pantalla dependiendo de cuánto muevas un eje. El cursor del ratón volverá al centro de la pantalla cuando el eje se mueva de nuevo a la zona muerta. Cursor Cursor Spring Muelle Acceleration: Aceleración: Enhanced Precision Precisión mejorada Linear Lineal Quadratic Cuadrática Cubic Cúbica Quadratic Extreme Cuadrática extrema Power Function Función potencial Easing Quadratic Cuadrática relajada Easing Cubic Cúbica relajada Mouse Speed Settings Configuración de velocidad del ratón Enable to change the horizontal and vertical speed boxes at the same time. Activar para cambiar la velocidad horizontal y vertical en ambos cuadros a la vez. Change Together Cambiar ambos ejes a la vez Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Opciones para añadir más aceleración al movimiento del ratón más allá del que produciría la curva de aceleración. La aceleración se añade en función de la rapidez con la que se mueve un eje.al sondear el mando. Esto se hace para solventar algunos de los problemas que produce el rango de entrada tan limitado de las típicas palancas analógicas de los mandos. Delta Acceleration Aceleración delta &Multiplier: &Multiplicador: Mi&n Threshold: Límite &mínimo: 1 = 20 pps 1 = 20 pps Wheel Hori. Speed: Vel. horiz. de la rueda: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Establece la velocidad a usar en el movimiento horizontal de la rueda según un número simulado de nudos por segundo. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Establece la velocidad a usar en el movimiento vertical de la rueda según un número simulado de nudos por segundo. Sensitivit&y: Sensi&bilidad: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Para la curva de aceleración de la función potencial. Especifica el factor a usar para la curva de sensibilidad. Cuando el valor sobrepasa 1.0, el movimiento del ratón se acelerará más rápido en el límite inferior de un eje. Easing Duration: Duración de relajación: s s Highest value to accelerate mouse movement by El valor más alto para acelerar el movimiento del ratón x x Start %: % ini.: Acceleration begins at this percentage of the base multiplier La aceleración comienza en este porcentaje del multiplicador base Minimum amount of axis travel required for acceleration to begin Cantidad mínima requerida de recorrido del eje para empezar la aceleración Max Threshold: Límite máximo: Maximum axis travel before acceleration has reached the multiplier value El recorrido máximo del eje antes de que la aceleración alcance el valor del multiplicador E&xtra Duration: Duración e&xtra: Curve: Curva: Ease Out Sine Seno relajada Ease Out Quad Cuadrática relajada Ease Out Cubic Cúbica relajada Release Radius: Radio de liberación: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Especifica que el área del muelle será relativa a la posición del ratón establecida por un muelle no relativo. Relative Relativo Mouse Status Estado del ratón X: X: 0 (0 pps) 0 (0 pps) Y: Y: 1 = 1 notch(es)/s 1 = 1 nudo(s)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Mejorado: Curva de tres niveles que hace que el ratón se mueva lento en el extremo inferior de un eje y rápido en el extremo superior. Lineal: El ratón se mueve proporcionalmente al eje. Cuadrático: El ratón acelera lentamente en el extremo inferior. Cúbico: El ratón acelera más lento que el cuadrático. Extremo cuadrático: Aumenta la velocidad del ratón 1,5 veces una vez Se ha alcanzado el 95% de desplazamiento por eje. Función de potencia: Permite una opción de curva más personalizada. Facilitar cuadrática: El extremo superior del eje se acelera gradualmente durante un período de tiempo utilizando una curva cuadrática. Facilitar Cubic: Axis high-end se acelera gradualmente sobre un período de tiempo utilizando una curva cúbica. Hori&zontal Speed: Velocidad hori&zontal: &Vertical Speed: Velocidad &vertical: Wheel Vert. Speed: Vel. vert. de la rueda: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. Especifica la cantidad de tiempo (en segundos) requerida antes de que el ratón acelere completamente tras alcanzar el límite superior de un eje. % % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Ampliar el tiempo en que se aplica la aceleracíon extra. Se tendrá en cuenta el recorrido del eje. Un movimiento más lento reducirá el tiempo en el que se aplicará la aceleración extra. Spring Settings Configuración de muelle Spring Width: Anchura de muelle: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Cambia la anchura de la región en la que el cursor se puede mover en modo muelle. 0 usará la anchura completa de la pantalla. Spring Height: Altura de muelle: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. Cambia la altura de la región en la que el cursor se puede mover en modo muelle. 0 usará la altura completa de la pantalla. %n notch(es)/s %n nudo/s %n nudos/s QKeyDisplayDialog Key Checker Verificador de Teclas <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> <html><head/><body><p>Presione una tecla en su teclado para ver cómo esta aplicación detecta la tecla. La ventana mostrará el valor de la clave nativa del sistema, el valor original proporcionado por Qt (si corresponde) y el valor personalizado utilizado por AntiMicroX.</p><p>El valor de la clave AntiMicroX y el valor de la clave Qt generalmente serán los mismos . AntiMicroX intenta usar los valores clave definidos en Qt cuando es posible. Consulte la página <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http ://doc.qt.io/qt-5/qt.html#Key-enum</span></a> para obtener una lista de valores definidos por Qt. Si descubre que una clave no es compatible de forma nativa con este programa, informe del problema a AntiMicroX <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">Página de GitHub</span></a> para que el programa se pueda editar para admitirlo directamente. Tal como está, se agrega un prefijo personalizado a los valores desconocidos para que aún puedan usarse; el principal problema es que el perfil ya no será portátil.</p></body></html> Event Handler: Manejador de eventos: Native Key Value: Valor de tecla nativo: 0x00000000 0x00000000 Qt Key Value: Valor de Tecla Qt: antimicro Key Value: Valor de tecla antimicro: QObject Super Súper Menu Menú Mute Silenciar Vol+ Subir el volumen Vol- Bajar el volumen Play/Pause Reproducir/Pausa Play Reproducir Pause Pausa Prev Anterior Next Siguiente Mail Correo Home Inicio Media Medios Search Buscar Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Su configuración original (anteriormente almacenada en %1) se ha copiado en %2 Si lo desea, puede eliminar el directorio original o dejarlo como está. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Se produjo algún problema con la migración de la configuración. Las configuraciones originales se almacenan en %1 pero su nueva ubicación es: %2 Puede migrar manualmente cambiando el nombre del directorio antiguo y cambiando el nombre del archivo a antimicrox_settings.ini. Quitting Program Saliendo del programa # of joysticks found: %1 # de mandos econtrados: %1 List Joysticks: Lista de mandos: --------------- --------------- Joystick %1: Mando %1: Attempting to use fallback option %1 for event generation. Intentando usar la opción alternativa %1 para la generación de eventos. Failed to open event generator. Exiting. Fallo al abrir el generador de eventos. Saliendo. Using %1 as the event generator. Usando %1 como generador de eventos. Last button Último botón There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? No hay un último botón presionado desde el mando en los datos. ¿Configuró al menos un botón del mando para el teclado? Specified contradicting flags: --show and --hidden Ha especificado opciones contradictorias: --show y --hidden Profile location %1 is not an XML file. La ubicación de perfil %1 no es un archivo XML válido. Profile location %1 does not exist. La ubicación de perfil %1 no existe. Controller identifier is not a valid value. El identificador del controlador no es un valor válido. An invalid set number '%1' was specified. Se ha especificado un número de conjunto inválido '%1'. Controller identifier '%s'' is not a valid value. El identificador de controlador '%s'' no es un valor válido. No set number was specified. No se ha especificado número de conjunto. An invalid event generator was specified. Se ha especificado un generador de eventos no válido. No event generator string was specified. No se ha especificado ninguna cadena de generador de eventos. Unknown log level: Nivel de registro desconocido: No log file specified. No se ha especificado archivo de registro. xinput version must be at least 2.0. No mouse acceleration changes will occur. La versión xinput debe ser al menos 2,0. No se producirán cambios en la aceleración del ratón. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: No se pueden abrir archivos uinput, esto puede causar problemas con la generación de eventos. Para comprobar las posibles soluciones, visite: QuickSetDialog Quick Set Configuración Rápida <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>Pulse un botón o mueva un eje en %1 (<span style=" font-weight:600;">%2</span>).<br/>Entonces aparecerá una ventana de diálogo<br/>que le permitirá crear una asignación.</p></body></html> Quick Set %1 Configuración rápida %1 SetAxisThrottleDialog Throttle Change Cambio de Acelerador The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? Se ha cambiado la posición del acelerador en el eje %1. ¿Le gustaría distribuir este cambio de acelerador a todos los conjuntos? SetJoystick Set %1: %2 Configurar %1: %2 Set %1 Configurar %1 SetNamesDialog Set Name Settings Configurar Nombres de Conjuntos Set 1 Conjunto 1 Set 2 Conjunto 2 Set 3 Conjunto 3 Set 4 Conjunto 4 Set 5 Conjunto 5 Set 6 Conjunto 6 Set 7 Conjunto 7 Set 8 Conjunto 8 Name Nombre SimpleKeyGrabberButton Mouse Ratón SpringModeRegionPreview Spring Mode Preview Vista Previa del Modo Muelle UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput No se ha podido encontrar un archivo de dispositivo uinput válido. Compruebe que tiene el módulo uinput cargado. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device No se ha podido abrir el archivo de dispositivo uinput Compruebe que tiene permiso para escribir en el dispositivo Using uinput device file %1 Usando archivo de dispositivo uinput %1 UInputHelper a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z Esc Esc F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace Retroceso Tab Tab [ [ ] ] \ \ CapsLock BlqMayús ; ; ' ' Enter Intro Shift_L Mayús_I , , . . / / Ctrl_L Ctrl_I Super_L Súper_I Alt_L Alt_I Space Espacio Alt_R Alt_D Menu Menú Ctrl_R Ctrl_D Shift_R Mayús_D Up Arriba Left Izquierda Down Abajo Right Derecha PrtSc ImpPant Ins Ins Del Supr Home Inicio End Fin PgUp RePág PgDn AvPág NumLock BlqNum * * + + KP_Enter TN_Intro KP_1 TN_1 KP_2 TN_2 KP_3 TN_3 KP_4 TN_4 KP_5 TN_5 KP_6 TN_6 KP_7 TN_7 KP_8 TN_8 KP_9 TN_9 KP_0 TN_0 SCLK BlqDesp Pause Pausa Super_R Súper_D Mute Silencio VolDn BajarVol VolUp SubirVol Play Reproducir Stop Parar Prev Anterior Next Siguiente [NO KEY] [SIN TECLA] UnixWindowInfoDialog Captured Window Properties Propiedades de la Ventana Capturada Information About Window Información sobre la ventana Class: Clase: TextLabel Etiqueta de texto Title: Titulo: Path: Ruta: Match By Properties Asignar por propiedades Class Clase Title Título Path Ruta VDPad VDPad CrucetaV VirtualKeyPushButton Space Espacio Tab Tab Shift (L) Mayús (I) Shift (R) Mayús (D) Ctrl (L) Ctrl (I) Ctrl (R) Ctrl (D) Alt (L) Alt (I) Alt (R) Alt (D) Alt Gr Alt Gr ` ` ~ ~ - - = = [ [ ] ] \ \ Caps BlqMayús ; ; ' ' , , . . / / ESC ESC PRTSC IMPPANT SCLK BLQDSP INS INS PGUP REPAG DEL SUPR PGDN AVPAG 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK BLQ NUM * * + + Enter Intro Del Supr < < : : Super (L) Súper (I) Menu Menú Up Arriba Down Abajo Left Izda Right Dcha VirtualKeyboardMouseWidget Keyboard Teclado Mouse Ratón Mouse Settings Configuración del ratón Left Mouse Ratón Izquierda Up Mouse Ratón Arriba Left Button Mouse Ratón Botón izquierdo Middle Button Mouse Ratón Botón central Right Button Mouse Ratón Botón derecho Wheel Up Mouse Ratón Rueda arriba Wheel Left Mouse Ratón Rueda izquierda Wheel Right Mouse Ratón Rueda derecha Wheel Down Mouse Ratón Rueda abajo Down Mouse Ratón Abajo Right Mouse Ratón Derecha Button 4 Mouse Ratón Botón 4 Mouse 8 Mouse Ratón Ratón 8 Button 5 Mouse Ratón Botón 5 Mouse 9 Mouse Ratón Ratón 9 NONE NINGUNA [NO KEY] [SIN TECLA] Last button Último botón Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Las ranuras para el botón no se pudieron borrar porque no había ningún botón establecido desde el teclado para el mando. Asigne al menos un botón del teclado al mando Others Otros Applications Aplicaciones Browser Back Navegador atrás Browser Favorites Navegador favoritos Browser Forward Navegador adelante Browser Home Navegador inicio Browser Refresh Navegador actualizar Browser Search Navegador buscar Browser Stop Navegador parar Calc Calcular Email Email F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media Medios Media Next Siguiente medio Media Play Reproducir medio Media Previous Medio anterior Media Stop Parar medio Search Buscar Volume Down Bajar volumen Volume Mute Silenciar volumen Volume Up Subir volumen VirtualMousePushButton INVALID NO VÁLIDO WinAppProfileTimerDialog Capture Application Capturar Aplicación After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Después de pulsar el botón "Capturar aplicación", seleccione la ventana de la aplicación que desea tener un perfil asociado. Se capturará la aplicación después del número de segundos seleccionado. Timer: Temporizador: Seconds Segundos Cancel Cancelar WinExtras [NO KEY] [SIN TECLA] AntiMicro Profile Perfil AntiMicro X11Extras ESC ESC Tab Tab Space Espacio DEL SUPR Return INTRO KP_Enter TN_Intro Backspace Retroceso Alt Gr Alt Gr xinput extension was not found. No mouse acceleration changes will occur. No se ha encontrado la extensión xinput. No se producirán cambios en la aceleración del ratón. xinput version must be at least 2.0. No mouse acceleration changes will occur. La versión de xinput debe ser al menos 2,0. No se producirán cambios en la aceleración del ratón. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 No se ha encontrado la clase PeerFeedback para el puntero virtual. No se producirá ningún cambio en la aceleración del ratón para el dispositivo con el id=%1 Changing mouse acceleration for device with id=%1 Cambiando la aceleración del ratón para el dispositivo con id=%1 XMLConfigReader Could not write updated profile XML to file %1. No se puede escribir XML del perfil actualizado en el archivo %1. XMLConfigWriter Could not write to profile at %1. No se pudo escribir el perfil en %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Programa gráfico utilizado para asociar los botones del teclado y los controles del ratón a un mando. Útil para jugar juegos sin soporte para mando. main Launch program in system tray only. Lanzar el programa en la bandeja del sistema únicamente. Launch program with the tray menu disabled Lanzar el programa con el menú de la bandeja deshabilitado Launch program without the main window displayed Lanzar el programa sin mostrar la ventana principal Show app window when hidden. (Used for unhiding window of already running app instance). Mostrar la ventana de la aplicación cuando esté oculta. (Usado para revelar la ventana de una instancia de la aplicación actualmente en ejecución). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers Lanzar el programa con el archivo de configuración seleccionado como predeterminado para los controladores seleccionados, o cambiar el perfil activo de la aplicación en ejecución. Por defecto a todos los controladores location ubicación Apply configuration file to a specific controller. Value can be a controller index, name, or GUID Aplicar el archivo de configuración a un controlador específico. El valor puede ser un índice de controlador, un nombre o un GUID value valor Unload currently enabled profile(s) Descargar el/los perfil(es) habilitado(s) actualmente value(s) valor(es) Start joysticks on a specific set. Value can be a controller index, name, or GUID Iniciar los joysticks en un conjunto específico. El valor puede ser un índice de controlador, un nombre o un GUID number value valor numérico Enable logging. Levels (from the least strict): warn,info,verbose,debug Habilitar registro. Niveles (desde el menos estricto): advertencia, información, verboso, depuración log-type tipo de registro Choose a file for logs writing Escoja un archivo para escribir el registro filename nombre de archivo Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. Escoja entre usar el soporte XTest y el soporte uinput para la generación de eventos. Usar únicamente si has habilitado las opciones xtest y uinput en Linux o vmulti en Windows. Por defecto: xtest. event-generation-type tipo de generación de eventos Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. Imprimir información sobre los mandos detectados por SDL. Usar únicamente si tienes la biblioteca sdl. Puede comprobar el índice del controlador, el nombre e incluso el GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_fa.ts000066400000000000000000013075301471077622000273560ustar00rootroot00000000000000 AboutDialog About درباره Version نسخه Info اطلاعات Changelog گزارش تغییرات Credits عوامل AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development درباره توسعه "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 حق نشر: 2013 - 2022 License مجوز Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 استفاده از رویداد گردان: %1 AddEditAutoProfileDialog Auto Profile Dialog Pro&file: Browse مرور Window: پنجره: Select Window. Click on the appropriate application window and the application file path will be populated in the form. پنجره را انتخاب کنید.روی برنامه مناسب کلیک کنید پنجره و مسیر فایل برنامه جمع خواهد شد در فرم. Detect Window Properties تشخیص مشخصات پنجره &Class: کلاس: T&itle: عنوان: set partial title تنظیم عنوانی جزئی Application: نرم‌افزار: Select انتخاب De&vices: دستگاه‌ها: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. این نمایه را انتخاب کنید تا به صورت پیش فرض بارگذاری شده باشد دستگاه مشخص شده در عوض از انتخاب استفاده می شود از گزینه تمام نمایه های پیشفرض. Set as Default for Controller انتخاب به عنوان دسته پیشفرض A different profile is already selected as the default for this device. یک پروفایل متفاوت از قبل به عنوان پیش فرض این دستگاه انتخاب شده است. Current (%1) اکنون (٪ 1) Open Config بازکردن پیکربندی Select Program انتخاب نرم‌افزار Programs (*.exe) نرم‌افزار ها (*.exe) Please use the main default profile selection. لطفاً از انتخابگراصلی نمایه پیش فرض استفاده کنید. Main Profile نمایه اصلی Already selected انتخاب شده Chosen Profile نمایه انتخاب شده The selection will be used instead of the all default profile option. انتخاب به جای گزینه مشخصات پیش فرض استفاده خواهد شد. Please select a window by using the mouse. Press Escape if you want to cancel. لطفاً با استفاده از ماوس یک پنجره را انتخاب کنید.اگر می خواهید لغو کنید ، Esc را فشار دهید. Capture Application Window Could not obtain information for the selected window. Application Capture Failed Profile file path is invalid. No window matching property was specified. Program path is invalid or not executable. File is not an .exe file. No window matching property was selected. AdvanceButtonDialog Advanced Assignments Toggle Turbo Set Selector Blank or KB/M Hold Pause Cycle Distance Insert Delete Clear All Time: 0.01s 0s Insert a pause that occurs in between key presses. Release Insert a new blank slot. Delete a slot. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. 0m &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: % Mouse Mod Press Time Delay Execute Load Set Change Text Entry Join Split Placeholder 0 Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After seconds Executable: ... Arguments: Enabled Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Delay: 0.10s Rate: 10.0/s Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] sec. /sec. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: Y Axis: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Down: Left: Right: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Haptic Trigger: Name: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Dead Zone: Max Zone: [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Attach the numeric keypad Last keyboard/mouse button: Slots Na&me: Specify the name of a button. Action: Specify the action that will be performed in game while this button is being used. Advanced Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel TextLabel X X gain offset Y Y Start calibration Close Reset settings Save Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAccelerometerButton Up Up Down Down Left Left Right Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Negative Positive Unknown Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Up Down Left Right LB MB RB Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] JoyControlStick Stick JoyControlStickButton Up Down Left Right Button JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: 0 Y: Distance: Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Down Left Right Button JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Button JoySensorContextMenu Mouse Settings Mouse Settings JoySensorEditDialog Dialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Safe Zone: Presets: Presets: Dead Zone: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: Diagonal Range: The area (in degrees) that each diagonal region occupies. The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Na&me: Na&me: Specify the name of an analog sensor. Mouse Settings Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None None Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad JoyTabWidget <New> Battery level of controller Remove Remove configuration from recent list. Load Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sensors DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Details Name: %1 Number: Axes: Buttons: Hats: Sensors: Battery: Unknown GUID: Game Controller: Axes Buttons Hats Sensors %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None None Axis %1 Hat %1 No Yes MainSettingsDialog Edit Settings General Controller Mappings Language Auto Profile Mouse Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Pro&file Directory: Show low battery notification Show empty battery notification Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID Mapping String Disable? Delete Default English Active Devices: All Device Profile Default? Add Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Options He&lp &Quit Ctrl+Q &Update Joysticks Ctrl+U &Hide Ctrl+H &About Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page (%1) Open File Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Failed to elevate program Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSensorSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Prev Next Mail Home Media Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name SimpleKeyGrabberButton Mouse SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 2 3 4 5 6 7 8 9 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK * + Enter Del < : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard Mouse Mouse Settings Left Mouse Up Mouse Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel WinExtras [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_fi.ts000066400000000000000000015520531471077622000273700ustar00rootroot00000000000000 AboutDialog About Tietoja AntiMicroX AntiMicroX Version Julkaisu Credits Tunnustuksellisuudet <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Alunperin kehittänyt Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Seuraavaksi AntiMicro ryhmän ylläpitämä https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sitten juliagoda :n toimesta https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Nyt ylläpidetty kohteessa https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Osallistujat:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Kielikääntäjät:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brasilian portugaliksi</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - kiinaksi</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - ranskaksi</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - saksaksi</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - saksaksi</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - venäjäksi</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - serbiaksi</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - ukrainaksi</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - espanjaksi</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - italiaksi</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - puolaksi</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> Info Tietopaketti License Käyttölupa <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU-hankkeen yleislupa (GPL)</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Julkaisuversio 3, 29 kesäkuu 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Tekijänoikeus (C) 2007 Free Software Foundation, järjestö. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Kuka tahansa voi jäljentää ja jakaa jäljennöksiä tästä lisenssiasiakirjasta mutta sen muokkaaminen ei ole sallittua.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Esipuhe</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public Lupa on vapaa ja ilmainen copyleft-käyttäjänoikeus lupa ohjelmistoille ja muille työstöille. Yleensä käyttöluvat useimmille tietokoneohjelmistoille sekä muille yleishyödyllisille sovelluksille ovat suunnitellut viemään sinun vapautesi pois jakaa ja muokata näitä sovelluksia. Päinvastaisesti, GNU-yleislupa eli GNU General Public License on juurikin tarkoitettiu takaamaan vapauksiesi säilyminen jakaaksesi ja muuttaaksesi ohjelman kaikkia versioita jotta tämä vapaus vapaille ohjelmistoille taataan kaikille käyttäjille. Me, vapaiden ohjelmistojen säätiönä, Free Software Foundation, käytämme GNU-yleislupaa (GNU General Public License) useimpien ohjelmistojemme kohdalla; se pätee myös muihin töihin joita sen tekijä julkaisee. Voit liittää sen myös omiin ohjelmasovelluksiisi.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Kun me puhumme vapaista ohjelmistoista , viittaamme todellakin vapauteen, emme rahaan. Yleislupamme ovat suunniteltu varmistamaan, että sinulla on vapaus jaella kopioita vapaista ohjelmista (sekä myös laskuttaa niistä rahaa jos haluat), että voit saada haltuusi lähdekoodin tai se toimitetaan sinulle näin halutessasi, että voit muuttaa ohjelmiston rakennetta tai käyttää sen osia uusia vapaita ohjelmia vasten, ja että tiedostat tämän olevan mahdollista ja luvallista.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Suojellaksemme oikeuksiasi, meidän tuleekin estää muita eväämästä sinulta näitä oikeuksia tai että joudut vaatimuksen eteen luopuaksesi niistä. Täten, sinulla onkin joitakin velvollisuuksia jos jakelet ohjelmistosi kopioita tai muokkaat niitä: velvollisuus kunnioittaa muiden ihmisten vapauksia.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Esimerkiksi, jos jaat kopioita jostakin tälläisestä ohjelmistosta, oli se sitten ilmainen tai maksullinen, vastaanottajan tulee nauttia samoista vapauksista kuin sinäkin teit. Sinun tulee varmistaa, että hekin saavat ohjelman lähdekoodin, ja että osoitat heille nämä samat ehdot jotta he voivat tietää oikeutensa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Kehittäjät jotka käyttävät GNU-yleislupaa, GNU GP, turvaavat oikeuksiasi kahden askeleen kautta:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) valtuuttavat ohjelmiston tekijänoikeuden, ja (2) tarjoavat sinulle tämän lupalisenssin joka antaa sinulle laillisen luvan kopioida, jakaa ja/tai muokata sitä.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Kehittäjien ja haltijoiden suojelemiseksi, GPL selventää selkeästi,että mitään takuuta tälle vapaalle ohjelmistolle ei tule. Molempien, käyttäjien ja tekijöiden hyväksi, GPL vaatii että muunnellut versiot pitää merkitä nimenomaan muokatuiksi, jotta heidän ongelmiansa ei liitetä virheellisesti tekijän aiempiin julkaisuihin.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Jotkut laitteet ovat suunnitellut eväämään käyttäjän mahdollisuuden asentaa tai ajaa muokattuja versioita laitteen sisällä olevasta ohjelmistosta, vaikkakin valmistaja voikin niin tehdä. Tälläinen käytös on lähtökohtaisesti sopimaton malli suojata käyttäjän vapautta muokata ohjelmistoa. Moista järjestelmällistä hyväksikäyttöä ilmenee usein yksilöiden käyttämissä loppukäyttäjälaitteissa joissa sellainen on vähiten hyväksyttävää. Tämän takia, olemme suunnitelleet tämän GPL:n version estämään moista käytäntöä noille laitteille. Mikäli moisia ongelmia nousee oleellisesti muissa käyttökohdissa, olemme valmiita laajentamaan tätä provisiota noihin käyttökohteisiin tulevaisuuden GPL-versioissa, aina sen mukaan, miten tarpeelliseksi nähdään jotta käyttäjän vapaudet tulevat suojelluiksi.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Lopulta, jokaista ohjelmaa uhkaillaan jatkuvasti ohjelmapatenttien tiimoilla. Maiden ei tulisi hyväksyä sellaisia patentteja jotka rajoittavat ohjelmistojen kehitystä ja käyttöä yleisissä tietokoneissa, mutta ne jotka tälläistä harjoittavat. koetamme välttää erityisvaaran joita patentit liitettynä vapaisiin ohjelmistoihin tuovat, ja tekisi tälläisestä ohjelmistosta siis omisteisen. Tämän estämiseksi, GPL varmistaa että näitä patenttaja ei voida langettaa ohjelman ei-vapaaksi saattamiseksi.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Tarkat käyttöehdot jäljentämiseen, jakeluun ja muokkaamiseen ovat seuraavassa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">KÄYTTÖEHDOT</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Määritykset.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Tämä lisenssi&quot; viittaa versioon 3 tästä GNU General Public License GNU-yleisluvasta.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Tekijänoikeus&quot; tarkoittaa myöskin tekijänoikeudenKALTAISIA lakeja jotka pätevät muihin töihin, kuten puolijohdenaamiot.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Ohjelma&quot; viittaa mihin tahansa tekijänoikeudella merkattavaan työhön tämän lisenssin alla. Luvitus liittyy&quot;sinuun&quot;. &quot;luvanalaisiin&quot; ja &quot;vastaanottajiin&quot; jotka voivat olla yksilöitä tai järjestöjä.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Muokataksesi &quot;jotakin&quot;työtä tarkoittaa kopiointia tai adaptoitumista, kaikkea tai osaa teoksesta niin että se vaatii tekijänoikeusluvan, joka on jokin muu kuin täsmäkopio. Tuloksena olevaa työtä kutsutaan &quot;muokatuksi versioksi&quot; aiempaan teokseen nähden &quot;perustuen&quot; aiempaan teokseen.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;"> &quot;katetut teokset&quot; tarkoittaa joko muokkaamatonta ohjelmistoa tai teosta joka perustuu tuohon teokseen.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;"> &quot;propagointi&quot; teoksen kohdalla tarkoittaa että että ilman lupaa pienikin muokaus tekisi sinusta suoraan tai epäsuorasti laillisesti vastuullisen kyseessä olevan tekijänoikeuslain kautta, paitsi että voit vain ajaa tuon ohjelman tietokoneessa tai muokataksesi yksityisen kopion. Propagaatio kattaa kopioinnin, jakelun (ilman tai kera muunnosten) tehden sen vapaaksi tarjolle kansalaisille ja joissakin maissa muihin käyttötarkoituksiin.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;"> &quot;välitys&quot; teoksen kohdalla tarkoittaa mitä tahansa propagointia joka mahdollistaa muut osapuolet tekemään tai vastaanottamaan kopioita. Pelkkä kanssakäyminen käyttäjän kanssa tietokoneverkon kautta ei ole sellaista toimintaa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Interktiiviset käyttöliittymäruudut &quot;Lainopilliset huomautukset&quot; siihen asti että nämä sisältävät käyttökelpoisen ja vankasti näkyvän ominaisuuden joka (1) näyttää tarkoituksenmukaisen tekijänoikeusilmoitteen, ja (2) kertoo käyttäjälle että takuuta teoksen piirissä ei ole (paitsi jos takuu annetaan), että luvitetut voivat välittää teosta tämän lisenssin alla, ja kuinka tarkastella tämän lienssin kopiota. Jos käyttöliittymä näyttää käyttäjäkomentoluettelon tai asetuksia, kuten asetusvalikko, tarkoituksenmukainen kohde täyttää nämä ehdot.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Lähdekoodi.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Itse &quot;lähdekoodi &quot; teoksen suhteen tarkoittaa suositeltavaa teoksen muotoa tehdä siihen muokkauksia.&quot;Objektikoodi&quot; tarkoittaa mitä tahansa ei-lähdellistä teoksen muotoa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Yleinen &quot;vakiokäyttöliittymä&quot; tarkoittaa käyttöliittymää joka on joko virallinen standardi jonka määrittää jokin tunnustettu standardin määrittävä taho, tai, jos kyseessä on käyttöliittymä jonka määrittää jokin tietty ohjelmointikieli, ja joka on yleisesti käytetty kehittäjien keskuudessa jotka työskentelevät tuon kielen kautta.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">itse &quot;järjestelmäkirjastot&quot; ajettavasta teoksesta sisältävät kaiken muun, paitsi itse teoksen kokonaisuutenaan, joka on (a) sisällytetty perinteiseen paketointimuotoon, pääkomponentiin, mutta joka ei ole osa tuota pääkomponenttia, ja (b) palvelee ainoastaan teoksen käyttöä tuon pääkomponentin kanssa, tai vakioliittymän täytäntöönpanemiseen joka on tarjolla julkisesti kaikille lähdekoodin muodossa. Kohteen &quot;pääkomponentti&quot;, tässä yhteydessä tarkoittaa erittäin tärkeän lähtökohtaista osasta (ydin, ikkunointijärjestelmä, ja niin edelleen) liittyen kyseessä olevaan käyttöjärjestelmään (mikäli sellainen on) jossa ajettava teos toimii, tai kokooja jota käytetään tuottamaan teos valmiiksi, tai objektikooditulkki jota käytetään sen ajamiseen.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Kohde &quot;vastaava lähde&quot; objektikoodityötä varten tarkoittaa kaikkea lähdekoodia joka tarvitaan muodostaa, asentaa ja (ajttavan tiedoston toimintaan) ajaa tuo objektikoodi ja muokata teosta, mukaan lukien skriptit joiden kautta noita toimia hallitaan. Tämä ei kuitenkaan sisällä teoksen järjestelmäkirjastoja, taikka yleistarkoituksellisia työkaluja, saati yleisesti tarjolla olevia vapaita ohjelmia joita käytetään muokkaamattomana joita käyteään noihin toimintoihin, mutta jotka eivät ole osa teosta. Esimerkiksi, vastaava lähde sisältää käyttöliittymää kuvaustiedostot, tiedostot jotka liittyvät kuvailutiedostoihin teoksen suhteen, ja lähdekoodi jaettujen kirjastojen suhteen sekä dynaamisesti linkatut aliohjelmat joita teos on suunniteltu vaatimaan, kuten intiimidatan hallinta noiden aliohjelmien ja teoksen osasten välillä.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Vastaavan lähteen ei tarvitse siältää mitään mitä käyttäjät voivat uudelleentuoda automaattisesti muista vastaavan lähteen osista.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Vastaava lähde teokselle lähdekoodimuodossa on tuota samaa teosta.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Peruslupaa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Kaikki oikeudet suotuna tämän lisenssin alla ovat sallitut ohjelman tekijänoikeusehdon mukaan, ja ovat täten palauttamattomissa kunhan kuvaillut ehdot täyttyvät. Tämä lisenssi nimenomaisesti varmentaa rajattoman oikeutesi ajaa muokkaamatonta ohjelmistoa. Tulema katetun teoksen ajamisesta on katettu tämän lisenssin kautta vain jos tulema, ottaen huomioon sen sisällön, on samasituva katetun työn suhteen. Tämä lisenssi tiedostaa oikeutesi ns. reiluun käyttöön (tai vastaavaan), kuten tekijänoikeuslaissa kerrotaan.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Voit valmistaa, ajaa ja propagoida katettuja teoksia joita et välitä, ilman ehtoja, mikäli lisenssisi muuten pysyy voimassa. Voit välittää katettuja teoksia muille heidän tehdäkseen tietyt halutut muutokset sinua varten, tai he voivat toimittaa sinulle avuja joiden kautta ajaa noita teoksia, kunhan olet samaa mieltä tämän lisenssin ehtojen kanssa välittäessäsi teosta joihin et omaa tekijänoikeushallintaa. Nämä sitten ovat tarkoitetut juuri sinun käyttöösi ja hallintaasi, niiden ehtojen mukaisesti jotka eväävät heidät tekemästä kopioita sinun nimissäsi oleviin tekijänoikeudella varustettuihin sovelluksiin, ilman suhdetta sinuun.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Välittäminen missään muussa tilanteessa on sallittu vain alla olevien ehtojen kautta.Aliluvittaminen ei ole sallittua; osio 10 vaatii sen.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Käyttäjien suojelu kiertämisen estävältä lailta.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Katettuja teoksia ei saa liittää osaksi efektiivisiä teknologisia toimia jotka ovat voimassa olevan lain voimaisia jotka täyttävät ehdot artikkelin 11 alla liittyen WIPO tekijänoikeussopimukseen joka otettiin käyttöön 20. Joulukuuta 1996, tai samankaltaisia lakeja jotka jotka kieltävät tai rajoittavat kiertämisen.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Kun välität katettua teosta, luovut kaikesta laillisesta omistusoikeudesta estääksesi teknisten tointen kiertämisen.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Kirjaimellisten kopioiden välitys.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Voit jaella kirjaimellisia kopioita ohjelman lähdekoodista sellaisena kuin sen saat, missä mediamuodossa tahansa, kunhan jokaisen kopion mukana toimitetaan tuo tekijänoikeusselvitys; mukana kaikki ilmoitteet joista selviää että tämä lisenssi ja kaikki ei-luvalliset ehdot jotka kuvaillaan osassa 7 ja pätevät koodin kanssa. Kaikki on oltava mukana ohjelman kanssa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Voit asettaa minkä tahansa rahallisen hinnan tai ei rahallista hintaa ollenkaan, jokaiselle kopiolle jonka välität ja jaat, ja voit tarjota tukea tai takuuta hintaa vastaan.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Muokatun lähdekoodin versioiden välitys.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Voit välittää teoksen joka vain perustuu lähtöteokseen, tai muokkauksiin jotka tekevät ohjelmasi, lähdekoodin muodossa kohdan 4 ehtojen mukaisesti, ottaen huomioon että myös nämä ehdot täyttyvät:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Teoksen tulee sisältää selonteko muutoksien tekemisestä päiväyksineen.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Teoksen tulee sisältää selonteko että teos on julkaistu tämän lisenssin alaisena ja lisäksi minkä tahansa ehdon kanssa jotka ovat määritelty osiossa 7. Tämä vaatimus muokkaa vaatimusta osiossa 4 jossa &quot;pyydetään pitämään mukana kaikki ilmoitteet&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Sinun tulee luvittaa koko teos, kokonaisuudessaan, tämän lupalisenssin alaiseksi jokaiselle joka saa siitä jäljenteen. Tämä lisenssi sitte pätee, osion 7 lisäehtojen kanssa koko teokseen ja sen osii, huolimatta siiitä kuinka teos toimitetaan tai on pakattu. Tämä lisenssi ei anna lupaa luvittaa tätä teosta millään muulla tavalla, but ei tee teosta epäkelvoksi mikäli olet saanut sen erillisenä.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Mikäli teoksessa on interaktiivia käyttöliittymiä, jokaiselle pitää sisällyttää asianmukaiset lailliset tiedonannot; kuitenkin, mikäli ohjelmassa on interaktiivisia käyttöliittymiä joista ei ilmene nämä lailliset selonteot, teoksesi ei tarvitse sitä toteuttaa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Kokoelma katettuja teoksia kera muiden itsenäisten teosten jotka eivät luonnostaan ole niiden jatkeita, ja joita ei yhdistetä teokseen isomman teoksen muodossa esim. säilömismedian sisällä &quot;kokonaisuus&quot; jos kokoelma ja sen tulokseksi muodostuvaa tekijänoikeutta ei käytetä rajoittamaan käyttöä tai laillisia oikeuksia kokoelman käyttäjien suhteen yli mitä yksilölliset teokset myöntävät. Katetun teoksen sisällyttäminen kokonaisuudessa ei johda tämän lisenssin pätemiseen muissa kokonaisuuden osissa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Ei-lähdellisten muotojen välitys.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Voit välittää katetun teoksen objektikoodimuodossa jotka esitetään kohdissa 4 ja 5, ottaen huomioon, että olet myös toimittanut konelukuisen vertaislähteen jotka ovat tämän lisenssin alaisia yhdessäkin näistä tavoista:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Välitä objektikoodi fyysisen tuotteen sisällä tai paketoinnissa (mukaanlukien fyysinen jakelumedia), jonka kanssa vertaislähde laitettuna fyysiselle medialle.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Välitä objektikoodi fyysisen tuotteen sisällä tai sen paketoinnissa (mukaanlukien fyysinen jakelumedia), jonka kanssa kirjoitettu tarjous vähintään kolmeksi vuodeksi voimassa olevaksi ja voimassa olevaksi niin kauan kuin tarjoat varaosia tai asiakastukea tuolle tuotemallille, antaaksesi kaikille jotka omaavat objektikoodin joko (1) vertaislähteen kopion kaikelle ohjelmistolle tuotteessa jota lisenssi kattaa, kestävälle fyysiselle medialle joka on suunniteltu vaihtamaan ja jakamaan ohjelmistotietoja, hinnalla joka ei olisi enempää kuin mikä kattaa kulut (2) käyttölupa ja avaimet kopioida vertaislähde verkkopalvelimelta ilman veloitusta.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Välittää yksilöllisiä kopioita objektikoodista kirjaillun tarjouksen kera vertaiskoodin suhteen. Tämä vaihtoehto sallitaan vain ajoittain ja ei-kaupallisesti, ja vain jos olet ottanut vastaan objektikoodin tämänlaisen tarjouksen ohessa joka täsmää osion 6b kanssa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Välitä objektikoodi tarjoamalla lupa käyttää sitä määrätystä paikasta (ilmaiseksi tai veloituksella ), ja tarjoa vertainen käyttömahdollisuus vertaislähteeseen samaan tapaan ilman lisäveloitusta. Sinun ei tarvitse vaatia vastaanottajan kopioida vertaislähdetä objektikoodin kanssa. Mikäli paikka josta objektikoodi kopioidaan on verkkopalvelin, vertainen lähde voi olla eri palvelimellakin (jota sinä tai kolmas osapuoli ylläpitää) joka tukee vertaisia kopiointikeinoja, ottaen huomioon että tarjoat selkeät ohjeet mitä tehdä ja mitä löytää mistäkin vertaiskoodin suhteen. Huolimatta mitä palvelinkulut tuolle koodille ovat, sinulla säilyy silti velvollisuus varmistaa että kaikki lisenssin kohdat täyttyvät.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Välittää objektikoodi käyttäen vertaisverkkoa ja siirtää sen kautta, kertoen muille vertaisverkkolaisille missä objektikoodi ja vertaislähde teokseen ovat tarjolla ladattavaksi kuten kohdassa 6d kerrotaan.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Eriteltävä osio objektikoodista, minkä lähdekoodi uupuu vastaavasta vertaislähteestä mutta järjestelmäkirjastona.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;"> &quot;Käyttäjätuote&quot; on joko (1) &quot;kuluttajatuote&quot;, joka tarkoittaa mitä tahansa tartuttavaa henkilökohtaista omaisuutta joka on yleisesti käytetty henkilökohtaiseen käyttöön, perhekäyttöön tai kotitalouskäyttöön; tai (2) mitä tahansa joka on suunniteltu tai myyty yhtiölle. Määritettäessä mikäli tuote on kuluttajatuote, epäröinnin edessä asia voidaan ratkaista kattavuuden mukaisesti. Tietty tuote jonka ottaa vastaan tietty käyttäjä&quot;normaalisti käytettynä&quot; viittaa tyypilliseen tai perinteiseen tuon tuotteen käyttöön, huolimatta kyseisen käyttäjän statuksesta tai tavasta jonka kautta käyttäjä käyttää, tai odottaa käyttävän tuotetta. Tuote on kuluttajatuote huolimatta siitä onko tuotteella mahdollista kaupallista, teollista tai ei-kuluttaja tyypin käyttökohtia ollenkaan, ellei tuotteella ole selvästi muuta kuin selkeästi vain tiettyä käyttökohtaa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Asennustiedot&quot; käyttäjätuotteella tarkoittaa mitä tahansa menetelmiä, käytäntöjä, isännöintiavaimia, tai muita informaatiota vaativia asioita jotka vaaditaan asennusta ja ajoa varten. Tietojen tulee aina riittää käytön jatkumiselle. Objektikoodi, vertaislähde jne.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Mikäli välität objektikooditeoksen tässä käsitellyin ehdoin, ne sisältäen tai kanssa, tai tarkemmin käyttötarkoituksen mukaan, kuluttajatuotteessa, ja välitys tapahtuu osana transaktiota jossa omistusoikeus ja kuluttajatuotteen käyttö siirretään vastaanottajalle toistaiseksi tai määrätyksi ajaksi (huolimatta miten transaktio luonnehditaan), vertaislähde välitettynä tämän osion ehtojen alla tulee laittaa mukaan asennusohjeeseen. Tämä vaatimus ei päde jos sinä tai mikään kolmas osapuoli ei omaa mahdollisuutta asentaa muokattua objektikoodia kuluttajatuotteen suhteen (esimerkiksi kun teos on asennettu ROM eli vain luku muodossa).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Vaatimus toimittaa asennustietoja ei sisällä vaatimusta jatkaa alati tukipalvelua, takuuta, tai päivityksiä teokselle jota on muokattu tai se on asennettu vastaanottajan toimesta, tai kuluttajatuotten suhteen jota on muokattu tai se on asennettu. Pääsy verkkoon voi olla evättynä kun muokkaus itsessään materisesti ja muodollisesti vaikuttaa verkon toimintaan tai rikkoo sääntöjä ja protokollia kommunikaatiolle kautta verkoston.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Vastaava lähde Source toimitettuna ja asennustiedot tarjottuna, täsmäten tämän osion kanssa, tuotteiden tulee olla muodossa joka on julkisesti dokumentoitu(kera implementaation myös tarjolla kansalle julkisesti lähdekoodin muodossa), ja mikään erikoissalasana ei saa olla vaatimuksena, taikka avainta jonka kautta voisi vasta purkaa paketin luettavaksi ja kopioitavaksi.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Lisäkäyttöehdot.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Lisäluvallisuudet&quot; ovat ehtoja jotka täydentävät tämän lisenssin ehtoja tehden poikkeuksia yhdestä tai kahdesta sen määrityksistä. Lisäluvat jotka soveltuvat koko ohjelmaan tulee käsitellä kuin jos ne olisivat sisällytetty tähän lisenssiin, siihen asti että ne ovat päteviä voimassa olevan lain kanssa. Mikäli lisälupia käytetään vain osaassa ohjelmaa, tuo osa voidaan käyttää erillisenä noiden lupien alaisena, mutta koko ohjelma säilyy tämän lisenssin alaisuudessa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Kun lähetät katetun teoksen kopion, voit halutessasi poistaa kaikki lisäluvat kyseisestä kopiosta tai sen mistä tahansa osasta. (Lisäluvat voidaan kirjoittaa siten, että ne on poistettava tietyissä tapauksissa, kun teosta muutetaan.) Voit sijoittaa lisälupia aineistoon, jonka olet lisännyt katettuun teokseen ja jolle sinulla on tai voit antaa asianmukaisen tekijänoikeusluvan.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Estämättä, mitä tämän lisenssin muissa määräyksissä määrätään, voit (aineiston tekijänoikeuksien haltijoiden luvalla) täydentää tämän lisenssin ehtoja aineistolla, jonka lisäät katettuun teokseen:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) takuusta luopuminen tai vastuun rajoittaminen tämän lisenssin 15 ja 16 kohdan ehdoista poiketen.; tai</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Vaatimus siitä, että tietyt kohtuulliset oikeudelliset merkinnät tai tekijämerkinnät säilytetään kyseisessä aineistossa tai sitä sisältävissä teoksissa olevissa asianmukaisissa oikeudellisissa merkinnöissä.; tai</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) kielletään kyseisen aineiston alkuperän virheellinen ilmoittaminen tai vaaditaan, että tällaisen aineiston muutetut versiot merkitään kohtuullisella tavalla alkuperäisestä versiosta poikkeaviksi.; tai</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Lisenssinantajien tai aineiston tekijöiden nimien käytön rajoittaminen julkisuustarkoituksiin.; tai</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) kieltäytyminen myöntämästä tavaramerkkilainsäädännön mukaisia oikeuksia joidenkin toiminimien, tavaramerkkien tai palvelumerkkien käyttöön; tai</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Vaaditaan, että jokainen, joka luovuttaa aineistoa (tai sen muunnettuja versioita) vastaanottajalle vastuuvelvollisuutta koskevien sopimusperusteisten olettamusten mukaisesti, korvaa aineiston lisenssinantajille ja tekijöille kaiken vastuun, jonka nämä sopimusperusteiset olettamukset suoraan aiheuttavat kyseisille lisenssinantajille ja tekijöille.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Kaikki muut lisäehdot, jotka eivät ole sallittuja, katsotaan kohdassa 10 tarkoitetuiksi lisärajoituksiksi. Jos vastaanottamassasi ohjelmassa tai sen osassa on ilmoitus siitä, että sitä koskee tämä Lisenssi, sekä ehto, joka on lisärajoitus, voit poistaa kyseisen ehdon. Jos lisenssiasiakirja sisältää lisärajoituksen, mutta sallii jälleenlisensoinnin tai luovuttamisen tämän lisenssin nojalla, voit lisätä katettuun teokseen aineistoa, jota koskevat kyseisen lisenssiasiakirjan ehdot, edellyttäen, että lisärajoitus ei säily tällaisessa jälleenlisensoinnissa tai luovuttamisessa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Jos lisäät ehtoja katettuun teokseen tämän jakson mukaisesti, sinun on sijoitettava asianomaisiin lähdetiedostoihin ilmoitus kyseisiin tiedostoihin sovellettavista lisäehdoista tai ilmoitus siitä, mistä sovellettavat ehdot löytyvät..</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Sallivat tai ei-sallivat lisäehdot voidaan ilmoittaa erillisenä kirjallisena lisenssinä tai ilmoittaa poikkeuksina; edellä mainittuja vaatimuksia sovelletaan kummallakin tavalla.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Mitätöinti.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Et saa levittää tai muokata teosta, jollei tässä lisenssissä nimenomaisesti toisin määrätä. Kaikki muut yritykset levittää tai muuttaa sitä ovat mitättömiä ja lopettavat automaattisesti tämän Lisenssin mukaiset oikeutenne (mukaan lukien kaikki kohdan 11 kolmannen kappaleen nojalla myönnetyt patenttilisenssit).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Jos kuitenkin lopetat kaiken lisenssirikkuruuden, tietyn tekijänoikeuden haltijan myöntämä lisenssi palautetaan (a) väliaikaisesti, ellei tekijänoikeuden haltija nimenomaisesti ja lopullisesti irtisano lisenssiäsi, ja (b) pysyvästi, jos tekijänoikeuden haltija ei ilmoita sinulle rikkomuksesta jollakin kohtuullisella tavalla ennen kuin 60 päivää on kulunut tämän lisenssin lopettamisesta..</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Lisäksi tietyn tekijänoikeuden haltijan myöntämä lisenssi palautetaan pysyvästi, jos tekijänoikeuden haltija ilmoittaa sinulle rikkomuksesta jollakin kohtuullisella tavalla, jos tämä on ensimmäinen kerta, kun olet saanut ilmoituksen tämän lisenssin rikkomisesta (minkä tahansa teoksen osalta) kyseiseltä tekijänoikeuden haltijalta, ja jos korjaat rikkomuksen ennen kuin 30 päivää on kulunut ilmoituksen vastaanottamisesta.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Tämän jakson mukaisten oikeuksiesi lakkauttaminen ei lakkauta niiden osapuolten lisenssejä, jotka ovat saaneet sinulta kopioita tai oikeuksia tämän lisenssin nojalla. Jos oikeutesi on lakkautettu eikä sitä ole palautettu pysyvästi, et ole oikeutettu saamaan uusia lisenssejä samaan aineistoon kohdan 10 mukaisesti.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Kopioiden ottaminen ei edellytä hyväksyntää.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Sinun ei tarvitse hyväksyä tätä lisenssiä saadaksesi tai käyttääksesi kopiota ohjelmasta. Myöskään lisenssin piiriin kuuluvan teoksen sivutoiminen levittäminen, joka tapahtuu pelkästään sen seurauksena, että kopion vastaanottamiseen käytetään vertaisverkkosiirtoa, ei edellytä hyväksyntää. Mikään muu kuin tämä lisenssi ei kuitenkaan anna sinulle lupaa levittää tai muuttaa mitään ohjelman kattamaa teosta. Nämä toimet rikkovat tekijänoikeuksia, jos et hyväksy tätä lisenssiä. Siksi muokkaamalla tai levittämällä katettua teosta osoitat hyväksyväsi tämän lisenssin.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automaattinen lisensointi lähteestä alaspäin toimiville tahoille.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Aina kun välität suojatun teoksen, vastaanottaja saa automaattisesti alkuperäisiltä lisenssinantajilta luvan käyttää, muokata ja levittää kyseistä teosta tämän lisenssin mukaisesti. Et ole vastuussa siitä, että kolmannet osapuolet noudattavat tätä lisenssiä.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;yhteisöliiketoimi&quot; on liiketoimi, jossa siirretään määräysvalta organisaatiossa tai olennaisilta osin sen koko omaisuudessa, tai jossa organisaatio jaetaan tai organisaatioita sulautetaan. Jos soveltamisalaan kuuluvan teoksen levittäminen on seurausta yhteisöliiketoimesta, jokainen liiketoimen osapuoli, joka saa teoksen kopion, saa myös kaikki teosta koskevat lisenssit, jotka edeltäjällä oli tai saattoi antaa edellisen kappaleen nojalla, sekä oikeuden saada teoksen vastaava lähde haltuunsa edeltäjältä, jos edeltäjällä on se tai hän voi kohtuullisin ponnistuksin saada sen.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Et saa asettaa muita rajoituksia tämän Lisenssin nojalla myönnettyjen tai vahvistettujen oikeuksien käytölle. Et saa esimerkiksi määrätä lisenssimaksua, rojalteja tai muita maksuja tämän lisenssin nojalla myönnettyjen oikeuksien käyttämisestä, etkä saa käynnistää oikeudenkäyntiä (mukaan lukien risti- tai vastakanne oikeudenkäynnissä), jossa väitetään, että mitä tahansa patenttivaatimusta on loukattu valmistamalla, käyttämällä, myymällä, tarjoamalla myyntiin tai maahantuonnilla ohjelmaa tai sen osaa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patentit.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;luovuttaja&quot; on tekijänoikeuden haltija, joka sallii ohjelman tai sellaisen teoksen, johon ohjelma perustuu, käytön tämän lisenssin nojalla. Näin lisensoitua teosta kutsutaan tekijänsä &quot;tekijäversioksi&quot;;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Osallistujan &quot;olennaiset patenttivaatimukset&quot; koskevat kaikkia patenttivaatimuksia, jotka ovat osallistujan omistuksessa tai määräysvallassa, riippumatta siitä, onko ne jo hankittu vai hankitaanko ne myöhemmin, ja joita loukattaisiin jollakin tämän lisenssin sallimalla tavalla, kun osallistujaversiota valmistetaan, käytetään tai myydään, mutta jotka eivät sisällä patenttivaatimuksia, joita loukattaisiin ainoastaan osallistujaversion lisämuutosten seurauksena. Tässä määritelmässä &quot;määräysvalta&quot; sisältää oikeuden myöntää patentin alilisenssejä tämän lisenssin vaatimusten mukaisella tavalla.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Kukin luovuttaja myöntää sinulle ei-yksinomaisen, maailmanlaajuisen, rojaltivapaan patenttilisenssin luovuttajan keskeisten patenttivaatimusten mukaisesti, jotta voit valmistaa, käyttää, myydä, tarjota myyntiin, tuoda maahan ja muutoin käyttää, muokata ja levittää luovuttajaversionsa sisältöä..</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Seuraavissa kolmessa kohdassa &quot;patenttilisenssillä&quot; tarkoitetaan mitä tahansa nimenomaista sopimusta tai sitoumusta, miten tahansa sitä kutsutaankin, olla panematta patenttia täytäntöön (kuten nimenomaista lupaa käyttää patenttia tai sitoumusta olla haastamatta patentinloukkausta oikeuteen). Tällaisen patenttilisenssin &quot;myöntäminen&quot; osapuolelle tarkoittaa, että tehdään tällainen sopimus tai sitoumus olla panematta patenttia täytäntöön osapuolta vastaan.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Jos välität suojatun teoksen tietoisesti luottaen patenttilisenssiin ja teoksen vastaava lähde ei ole kenen tahansa kopioitavissa maksutta ja tämän lisenssin ehtojen mukaisesti julkisesti saatavilla olevan verkkopalvelimen tai muun helposti saatavilla olevan keinon kautta, sinun on joko (1) saatettava vastaava lähde saataville, tai (2) järjestettävä, että menetät patenttilisenssistä saatavan edun kyseisen teoksen osalta, tai (3) järjestettävä tämän lisenssin vaatimusten mukaisesti patenttilisenssin ulottaminen myöhempiin vastaanottajiin. &quot;tietoisesti luottaen&quot; tarkoittaa, että sinulla on tosiasiallinen tieto siitä, että ilman patenttilisenssiä katetun teoksen välittäminen jossakin maassa tai katetun teoksen käyttäminen vastaanottajasi toimesta jossakin maassa loukkaisi yhtä tai useampaa kyseisessä maassa olevaa tunnistettavaa patenttia, jonka sinulla on syytä uskoa olevan voimassa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Jos yhden ainoan liiketoimen tai järjestelyn nojalla tai sen yhteydessä välität tai levität suojatun teoksen tai levität sitä välittämällä ja myönnät joillekin suojatun teoksen vastaanottajille patenttilisenssin, joka oikeuttaa heidät käyttämään, levittämään, muuttamaan tai välittämään suojatun teoksen tiettyä kappaletta, myöntämäsi patenttilisenssi laajenee automaattisesti koskemaan kaikkia suojatun teoksen ja siihen perustuvien teosten vastaanottajia.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Patenttilisenssi on &quot;syrjivä&quot;, jos se ei sisälly kattavuuteensa, kieltää yhden tai useamman tässä lisenssissä erityisesti myönnetyn oikeuden käyttämisen tai asettaa sen ehdoksi, että yhtä tai useampaa oikeutta ei käytetä. Et saa välittää katettua teosta, jos olet osapuolena kolmannen osapuolen kanssa tehdyssä järjestelyssä, joka harjoittaa ohjelmistojen jakelua ja jonka mukaan maksat kolmannelle osapuolelle maksun, joka perustuu teoksen välitystoimintasi laajuuteen, ja jonka mukaan kolmas osapuoli myöntää, mille tahansa osapuolelle, joka saisi katetun teoksen sinulta, syrjivän patenttilisenssin a) toimittamiesi suojatun teoksen kopioiden (tai näistä kopioista tehtyjen kopioiden) osalta tai b) ensisijaisesti tiettyjä suojatun teoksen sisältäviä tuotteita tai koosteita varten ja niiden yhteydessä, paitsi jos olet tehnyt kyseisen järjestelyn tai kyseinen patenttilisenssi on myönnetty ennen 28.3.2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Mitään tässä lisenssissä ei saa tulkita siten, että se sulkee pois tai rajoittaa mitään implisiittistä lisenssiä tai muita loukkausta koskevia puolustautumiskeinoja, jotka voivat muutoin olla käytettävissäsi sovellettavan patenttilainsäädännön nojalla.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. Muiden vapauksia ei voi alistaa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Jos sinulle asetetaan ehtoja (tuomioistuimen päätöksellä, sopimuksella tai muulla tavoin), jotka ovat ristiriidassa tämän lisenssin ehtojen kanssa, ne eivät vapauta sinua sen ehdoista. Jos et voi välittää teosta siten, että täytät samanaikaisesti tämän lisenssin mukaiset velvollisuutesi ja kaikki muut asiaankuuluvat velvollisuutesi, et saa välittää teosta lainkaan. Jos esimerkiksi suostut ehtoihin, jotka velvoittavat sinut keräämään rojaltin ohjelman edelleen välittämisestä niiltä, joille välität ohjelman, ainoa tapa, jolla voisit täyttää sekä nämä ehdot että tämän lisenssin vaatimukset, olisi pidättäytyä kokonaan ohjelman välittämisestä.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Käyttö GNU Affero General Public -luvituksen alla</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Tämän lisenssin muista määräyksistä huolimatta sinulla on lupa linkittää tai yhdistää mikä tahansa lisenssin piiriin kuuluva teos GNU Affero General Public License -lisenssin version 3 alaisen teoksen kanssa yhdeksi yhdistetyksi teokseksi ja välittää tuloksena syntynyt teos. Tämän lisenssin ehtoja sovelletaan edelleen siihen osaan, joka on katettu teos, mutta GNU Affero General Public License -lisenssin kohdan 13 erityisvaatimukset, jotka koskevat vuorovaikutusta verkon kautta, koskevat yhdistelmää sellaisenaan.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Tämän lisenssin uudistetut versiot.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Free Software Foundation -säätiö saattaa julkaista ajoittain tarkistettuja ja/tai uusia versioita GNU General Public License -lisenssistä. Tällaiset uudet versiot ovat hengeltään samankaltaisia kuin nykyinen versio, mutta voivat poiketa yksityiskohdiltaan uusien ongelmien tai huolenaiheiden käsittelemiseksi.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Jokaiselle versiolle annetaan oma versionumeronsa. Jos ohjelmassa ilmoitetaan, että siihen sovelletaan tiettyä GNU General Public License -lisenssin &quot;tai jonkin myöhemmän version&quot; numeroitua versiota, sinulla on mahdollisuus noudattaa joko kyseisen numeroidun version tai jonkin myöhemmän Free Software Foundationin julkaiseman version ehtoja. Jos ohjelmassa ei mainita GNU General Public License -lisenssin versionumeroa, voit valita minkä tahansa Free Software Foundationin koskaan julkaiseman version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Jos ohjelmassa määritetään, että välittäjä voi päättää, mitä GNU General Public License -lisenssin tulevia versioita voidaan käyttää, kyseisen välittäjän julkinen lausunto version hyväksymisestä valtuuttaa sinut pysyvästi valitsemaan kyseisen version ohjelmaa varten.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Myöhemmät lisenssiversiot voivat antaa sinulle lisää tai erilaisia oikeuksia. Kenellekään tekijälle tai tekijänoikeuksien haltijalle ei kuitenkaan aseteta lisävelvoitteita sen seurauksena, että valitset myöhemmän version noudattamisen.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Takuun vastuuvapauslauseke.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">OHJELMALLE EI MYÖNNETÄ TAKUUTA SOVELLETTAVAN LAIN SALLIMISSA RAJOISSA. Jollei toisin ole kirjallisesti ilmoitettu, TEKIJÄNOIKEUDEN OMISTAJAT JA/TAI MUUT OSAPUOLET TARJOAVAT OHJELMAN "sellaisena kuin se on" ilman minkäänlaista takuuta, joko nimenomaista tai epäsuoraa, mukaan lukien, mutta ei rajoitetusti, epäsuorat takuut kaupallisesta kelpaavuudesta ja soveltuvuudesta tiettyyn käyttötarkoitukseen. KOKO RISKI OHJELMAN LAADUSTA JA SUORITUSKYVYSTÄ ON SINULLA. JOS OHJELMA OSOITTAUTUU VIALLISEKSI, SINÄ VASTAAT KAIKISTA TARVITTAVISTA HUOLTO-, KORJAUS- TAI KORJAUSKUSTANNUKSISTA.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Vastuun rajoittaminen.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TEKIJÄNOIKEUDEN HALTIJA TAI MUU OSAPUOLI, JOKA MUUTTAA JA/TAI LUOVUTTAA OHJELMAA EDELLÄ SALLITULLA TAVALLA, EI OLE MISSÄÄN TAPAUKSESSA VASTUUSSA SINULLE VAHINGOISTA, MUKAAN LUKIEN YLEISET, ERITYISET, SATUNNAISET TAI VÄLILLISET VAHINGOT, JOTKA JOHTUVAT OHJELMAN KÄYTÖSTÄ TAI KYVYTTÖMYYDESTÄ KÄYTTÄÄ OHJELMAA (MUKAAN LUKIEN, MUTTA EI RAJOITTUEN, TIETOJEN MENETTÄMINEN TAI TIETOJEN MUUTTUMINEN EPÄTARKOIKSI TAI SINUN TAI KOLMANSIEN OSAPUOLTEN KÄRSIMÄT MENETYKSET TAI OHJELMAN TOIMIMATTOMUUS YHDESSÄ MUIDEN OHJELMIEN KANSSA), PAITSI JOS TEKIJÄNOIKEUDEN HALTIJAAN TAI MUUHUN OSAPUOLEEN ON ILMOITETTU TÄLLAISTEN VAHINKOJEN MAHDOLLISUUDESTA, PAITSI JOS SITÄ ON VAADITTU SOVELLETTAVASSA LAISSA TAI SIITÄ ON SOVITTU KIRJALLISESTI.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Osioiden 15 ja 16 tukinta.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Jos edellä mainituille takuusta luopumiselle ja vastuun rajoittamiselle ei voida antaa paikallista oikeusvaikutusta niiden ehtojen mukaisesti, muutoksenhakutuomioistuinten on sovellettava paikallista lakia, joka lähimpänä vastaa ehdotonta luopumista kaikesta siviilioikeudellisesta vastuusta ohjelmaan liittyen, paitsi jos takuu tai vastuunottovelvollisuus liitetään ohjelman kopioon maksua vastaan.</span></p></body></html> Changelog Kirjaukset muutoksista About Development Tietoja kehitystyöstä "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. "pktiuk" (elokuu 2020) haluan vain varmistaa, että tätä erittäin hyödyllistä ohjelmistoa ei hylätä, päätin jatkaa tämän hankeen tukemista ja tehdä siitä mahdollisimman laajasti saatavan. "juliagoda" (maaliskuusta 2018 vuoteen 2020) halusin vain pelata vanhoja suosikkipelejäni, jotka eivät tukeneet gamepadeja, joten löysin tämän projektin (joka kartoittaa näppäimistön näppäimet ja hiiren painikkeet liitetyille gamepadeille Linuxissa) kaikkein asianmukaisimmin ja ajanmukaisimmin. Mutta koska tällaisille sovelluksille on huonoja vaihtoehtoja internetissä ja koska se ei jatkunut asianmukaisesti, päätin pelastaa projektin. Kuitenkin, kun sain työni valmiiksi (ainakin tarpeeksi nauttiakseni pelien pelaamisesta sillä), ajattelin jakaa tämän ohjelmakoodin muiden kanssa. Tietenkin kaikki tiedot aiemmista ohjelmoijista pidetään yllä. "Ryochan7" (30. joulukuuta 2012 alkaen vuoteen 2017 asti), olen työskennellyt AntiMicron parissa vapaa-ajallani. Se, mikä alun perin alkoi QJoyPadin haarana ja tapana oppia kunnollista tapahtumapohjaista ohjelmointia, on muuttunut joksikin paljon suuremmaksi kuin alun perin ajattelin. Vaikka olen käyttänyt paljon aikaa uusien tekniikoiden oppimiseen, KB+M-emuloinnin alaan perehtymiseen ja perjantai-iltojen viettämiseen hakkaamalla päätäni näppäimistöön, se on ollut kaikenkaikkiaan hauska ja rikastuttava kokemus. Tarve tälle ohjelmalle tuli siitä, että käytin vastaavia ohjelmia Windowsissa pelatakseni useita pelejä, joissa ei ollut natiivia ohjaintukea. Vaikka Linuxissa oli joitain vaihtoehtoja, ei ollut oikeastaan mitään sellaista, joka olisi ollut mielestäni tarpeeksi hyvä toiminnallisuuden kannalta. Siitä lähtien olen yrittänyt selvittää, mitä muut ohjelmat tekevät oikein, ja parantanut sitä. Olen myös keksinyt matkan varrella joitakin hienoja temppuja ja oppinut enemmän siitä, miten natiivit gamepad-ohjaimet on toteutettu joissakin peleissä, kuin olen koskaan halunnutkaan tietää. Vaikka tässä ohjelmassa on varmasti alueita, joilla sitä voisi parantaa, minusta tämä ohjelma tarjoaa parhaan ohjauskokemuksen pelissä pelatessa vanhempia ja joitakin uudempia pelejä, jotka eivät tarjoa natiivia ohjaintukea. Tämän ohjelman kehittäminen ei ole enää prioriteetti minulle. Tämä johtuu pääasiassa siitä, että Steam-ohjain toimii melko hyvin PC-pelien pelaamiseen verrattuna Xbox 360 -ohjaimen käyttöön. Näyttää kuitenkin siltä, että tämän ohjelman olemassaololle on vielä jonkin aikaa hyvä syy. --- 24. toukokuuta 2016 alkaen tämä hanke on siirretty osoitteeseen https://github.com/AntiMicro/antimicro. Lisäksi projektin hallinta on siirtynyt Travisilta (Ryochan7) AntiMicro-organisaatiolle, koska Travisilla on muita kiinnostuksen kohteita ja prioriteetteja. Seuraavana projektia on vuodesta 2018 lähtien jatkanut juliagoda antimicroX-projektissa. Myöhemmin projekti on jälleen kerran siirretty osoitteeseen https://github.com/AntiMicroX/antimicrox ja sen ylläpitoa jatkaa pktiukin luoma AntiMicroX-organisaatio. Copyright: 2013 - 2022 Tekijänoikeus: 2013 - 2022 Program Version %1 Ohjelman versio %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Ohjelma koottu %1 ajassa %2 Built Against SDL %1 Rakennettu SDL:ää vasten %1 Running With SDL %1 Ajossa SDL:llä %1 Using Qt %1 Qt:n käyttö %1 Using Event Handler: %1 Tapahtumakäsittelijän käyttö: %1 AddEditAutoProfileDialog Auto Profile Dialog Automaattiprofiilin ilmoite Pro&file: Pro&fiili: Browse Selaa Window: Ikkuna: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Valitse ikkuna. Napsauta asiaankuuluvassa sovellus ikkunassa ja sovelluksen tiedostopolku määritetään kaavassa. Detect Window Properties Havainnoi ikkuna-asetukset &Class: &Luokka T&itle: N&imike: set partial title aseta osittaisnimike Application: Sovellus: Select Valitse De&vices: Lai&tteet: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Valitse tämä profiili ladattavaksi vakiollisesti kyseiseen laitteeseen. Tätä profiilia tullaan käyttämään kaikkien muiden profiilivaihtoehtojen sijasta. Set as Default for Controller Aseta vakiolliseksi peliohjaimelle Current (%1) Nykyinen (%1) Open Config Avaa asetukset Select Program Valitse ohjelma Programs (*.exe) Ohjelmat (*.exe) Please use the main default profile selection. Käytäthän pääasiallista ja vakiollista profiilivalintaa. Main Profile Pääprofiili Already selected Valittu jo A different profile is already selected as the default for this device. Eri profiili on jo valittu vakiolliseksi tälle laitteelle. Chosen Profile Valittu profiili The selection will be used instead of the all default profile option. Valintaa tullaan käyttämään kaikkien vakiollisten profiilivaihtoehtojen sijaan. Please select a window by using the mouse. Press Escape if you want to cancel. Valitse ikkuna hiirtä käyttäen. Paina Escape-nappia mikäli haluat keskeyttää. Capture Application Window Kaappaa sovelluksen ikkuna Could not obtain information for the selected window. Valitusta ikkunasta ei voitu noutaa tietoja. Application Capture Failed Sovelluskaappaus epäonnistui Profile file path is invalid. Profiilin tiedostopolku on epäkelpo. No window matching property was specified. Ikkunaa vastaavaa ominaisuutta ei oltu määritetty. Program path is invalid or not executable. Ohjelmapolku on epäkelpo tai sen kautta ei voida sovellusta ajaa. File is not an .exe file. Tiedosto ei ole .exe -tiedostomuotoa. No window matching property was selected. Ikkunaa vastaavaa ominaisuutta ei valittu. AdvanceButtonDialog Advanced Edistyneet Assignments Tehtävät Toggle Kytkentä Turbo Turbo Set Selector Aseta valitsin Blank or KB/M Tyhjä tai KB/M Cycle Kierrätä Delay Viive Distance Etäisyys Execute Aja Hold Pidättele Load Lataa Mouse Mod Hiirimuokkain Pause Tauko Press Time Painalluksen aika Release Irtipäästö Set Change Aseta muutos Text Entry Tekstisyöte Insert a new blank slot. Syötä uusi tyhjä osio. Insert Syötä Delete a slot. Poista osio. Delete Poista Join Liitä Split Jaa Clear all currently assigned slots. Tyhjää kaikki nykyisellään määritellyt osiot. Clear All Tyhjää kaikki Placeholder Kannatin Specify the duration of an inserted Pause or Hold slot. Määritä syötetyn tauotuksen- tai alhaallapidon kesto. Time: Aika: 0.01s 0.01s 0m 0m 0 0 0s 0s &Mouse Speed Mod: &Hiiren nopeuden muovaus: Set the percentage that mouse speeds will be modified by. Aseta prosenttimäärä jonka kautta hiiren nopeutta tullaan muokkaamaan. % % Specify the range past an axis dead zone in which a sequence of actions will execute. Aseta liikkuma-ala kuolleen alueen ohi jossa toimintojen sarja tullaan toteuttamaan. Distance: Etäisyys: Auto Reset Cycle After Nollaa kierros automaattisesti heti perään seconds sekunnit Choose Profile Valitse profiili Executable: Ajettava tiedosto: ... ... Arguments: Määrittelyt: Enabled Kytketty Mode: Tila: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>Perinteinen: paina nappia alas ja ylös toistuvasti valitun määreen mukaisesti.</p><p>Kaltevuus: muokkaa napin painallusta ja vapaaksi päästöä perustuen siihen miten kauaksi akselissa ollaan liikuttu. Vauhtisuhde pysyy samana.</p><p>Pulssi: muokkaa montako kertaa nappia painetaan ja päästetään takaisin ylös joka sekunti. Napin viive pysyy samana.</p></body></html> Normal Perinteinen Gradient Kaltevuus Pulse Pulssi Delay: Viive: 0.10s 0.10s Rate: Vauhtivaste: 10.0/s 10.0/s Disabled Pois päältä Select Set 1 One Way Valitse valikoima 1 Yksisuuntainen Select Set 1 Two Way Valitse valikoima 2 Kaksisuuntainen Select Set 1 While Held Valitse valikoima 1 Kun nappia pidetään pohjassa Select Set 2 One Way Valitse valikoima 2 Yksisuuntainen Select Set 2 Two Way Valitse valikoima 2 Kaksisuuntainen Select Set 2 While Held Valitse valikoima 2 Kun nappia pidetään pohjassa Select Set 3 One Way Valitse valikoima 3 Yksisuuntainen Select Set 3 Two Way Valitse valikoima 3 Kaksisuuntainen Select Set 3 While Held Valitse valikoima 3 Kun nappia pidetään pohjassa Select Set 4 One Way Valitse valikoima 4 Yksisuuntainen Select Set 4 Two Way Valitse valikoima 4 Kaksisuuntainen Select Set 4 While Held Valitse valikoima 4 Kun nappia pidetään pohjassa Select Set 5 One Way Valitse valikoima 5 Yksisuuntainen Select Set 5 Two Way Valitse valikoima 5 Kaksisuuntainen Select Set 5 While Held Valitse valikoima 5 Kun nappia pidetään pohjassa Select Set 6 One Way Valitse valikoima 6 Yksisuuntainen Select Set 6 Two Way Valitse valikoima 6 Kaksisuuntainen Select Set 6 While Held Valitse valikoima 6 Kun nappia pidetään pohjassa Select Set 7 One Way Valitse valikoima 7 Kaksisuuntainen Select Set 7 Two Way Valitse valikoima 7 Kaksisuuntainen Select Set 7 While Held Valitse valikoima 7 Kun nappia pidetään pohjassa Select Set 8 One Way Valitse valikoima 8 Yksisuuntainen Select Set 8 Two Way Valitse valikoima 8 Kaksisuuntainen Select Set 8 While Held Valitse valikoima 8 Kun nappia pidetään pohjassa [NO KEY] [EI NAPPIA] sec. sek. /sec. /sek. Not checked slots Ei-tarkistetut osiot To delete slots, you need to select at least one Poistaaksesi osioita, sinun tulee valita vähintäänkin yksi To insert slots, you need to select at least one Syöttääksesi osioita, sinun tulee valita vähintäänkin yksi Unknown current slot Tuntematon nykyosio Click on chosen slots before joining them Napsauta valitussa osiossa ennen liittämistä Not enough slots Osioita ei ole tarpeeksi It's impossible to join slots. Add at least one other slot. Osioita on mahdoton liittää. Lisää ainakin yksi osio. Not selected slots Ei valittuja osioita It's impossible to join slots. Select at least two slots before joining them Osioita on mahdoton liittää. Lisää ainakin kaksi osiota ennen liittämistä Only keyboard slots Vain näppäimistöosiot It's only possible to join simple and mix keyboard slots On mahdollista liittää vain yksinkertaisia ja yhdistettyjä näppäimistöosioita It's impossible to split slots. Add at least one other slot. Osioita on mahdoton jakaa. Lisää ainakin yksi osio lisää. Not selected slot Ei valittu osio Select your slot before splitting. Valitse osiosi ennen jakamista. Too many mix slots Liian monta sekoitettua osiota Select one mix slot. Valitse yksi sekoitusosio. Only mix slots Vain sekaosiot It's only possible to split mix slot. On mahdollista jakaa vain sekaosio. Empty execution path Tyhjää ajettava polku Line for execution file path is empty. Fill the first line before you are going to add a slot. Ajettavan tiedostopolun rivi on tyhjä. Täytä ensimmäinen rivi ennen kuin aiot lisätä osion. File doesn't exist Tiedostoa ei ole olemassa There is no such file locally, that could be executed. Check the file on your system Tuollaista tiedostoa, joka voitaisiin ajaa, ei löydy paikallisesti. Tarkista järjestelmäsi tiedoston suhteen Set %1 Aseta %1 Select Set %1 Valitse valikoima %1 One Way Yksisuuntainen Two Way Kaksisuuntainen While Held Kun nappia pidetään pohjassa Config Files (*.amgp *.xml) Asetustiedostot (*.amgp *.xml) Choose Executable Valitse ajettava Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Osiot jatkumotoiminnon jälkeen tullaan ajamaan seuraavalla napinpainalluksella. Useita jatkumoita voidaan lisätä partitiosarjan saavuttamiseksi. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Viivyttää hetkeä jolloin seuraava määrityslokero aktivoidaan määritetyn ajan mukaan. Määrityslokerot jotka aktivoidaan ennen viivettä pysyvät aktiivisena sen jälkeen kun viiveaika on ohitettu. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Etäisyyden toiminto määrittää että määrityslokerot jälkeenpäin toimitetaan vain silloin kun akselilla liikutaan ohi tietyn etäisyyden määritetyn kuolleen alueen jälkeen. Execute program when slot is activated. Suorita ohjelma kun määritelokero aktivoituu. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Aseta painikkeen alhaallapito. Määrityslokerot toimituksen jälkeen ajetaan vain mikäli painiketta pidetään alhaalla yli määritetyn ajanjakson. Chose a profile to load when this slot is activated. Valitse ladattava profiili tämän määrityslokeron aktivoituessa. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Hiiren muokkaustoiminto muokkaa kaikkia hiiren nopeusasetuksia määritetyn prosenttiluvun mukaisesti kun toimintoa käsitellään. Tämä voi olla hyödyllinen hidastamaan hiirtä samalla kun tähtäät tarkasti. Insert a pause that occurs in between key presses. Aseta taukomääre joka toteutetaan nappien painallusten välissä. Specify the time that keys past this slot should be held down. Määritä aika jonka jälkeen painikkeet alaspainatetaan. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Aseta napin vapauttamisen toiminto. Määrityslokerot ajetaan toiminnon jälkeen vain silloin kun nappi päästetään ylös jos nappia pidettiin alhaalla ohi määritetyn aikaikkunan. Change to selected set once slot is activated. Vaihda valittuun kokoelmaan kun määritelokero aktivoituu. Full string will be typed when a slot is activated. Täydellinen sarja kirjoitetaan määritelokeron aktivoituessa. AdvanceStickAssignmentDialog Stick/Pad Assignment Sauvan/padin määritykset Sticks Sauvat DPads Dpadit Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. Huomautus: tämä ikkuna on tarkoitettu taaksepäin yhteensopivuuden saavuttamiseksi profiilien kanssa jotka ovat tehdyt ennen antimicron julkaisua 2.0. Julkaisun 2.0 jälkeen, Peliohjainkartoitus -ikkunaa suositellaan. %1 (Joystick %2) %1 (Sauvaohjain %2) Stick 1 Sauva 1 Enabled Kytketty Assign Määrittele X Axis: X-akseli: Y Axis: Y-akseli: Stick 2 Sauva 2 Number of Physical DPads: %1 Fyysisten Dpadien lukumäärä: %1 Virtual DPad 1 Virtuaali-Dpadi 1 Down: Alas: Left: Vasen: Right: Oikea: Up: Ylös: Axis %1 Akseli %1 Axis %1 - Akseli %1 - Axis %1 + Akseli %1 + Button %1 Painike %1 Move stick 1 along the X axis Liikuta sauvaa 1 pitkin X-akselia Move stick 1 along the Y axis Liikuta sauvaa 1 pitkin Y-akselia Move stick 2 along the X axis Liikuta sauvaa 2 pitkin X-akselia Move stick 2 along the Y axis Liikuta sauvaa 2 pitkin Y-akselia Press a button or move an axis Paina nappia tai liikuta akselilla AxisEditDialog Axis Akseli Presets: Vakiot: Mouse (Horizontal) Hiiri (vaakataso) Mouse (Inverted Horizontal) Hiiri (käänteinen vaakataso) Mouse (Vertical) Hiiri (pystysuunta) Mouse (Inverted Vertical) Hiiri (käänteinen pystysuunta) Arrows: Up | Down Nuolet: ylös | alas Arrows: Left | Right Nuolet: vasen | oikea Keys: W | S Näppäimet: W | S Keys: A | D Näppäimet: A | D NumPad: KP_8 | KP_2 Numeronäppäimistö: NP_8 | NP_2 NumPad: KP_4 | KP_6 Numeronäppäimistö: NP_4 | NP_6 None Ei mitään Set the value to use as the limit for an axis. Useful for a worn out analog stick. Aseta arvo jota käytetään rajana akselilla. Kätevä jos kyseessä on kulunut analoginen ohjain. Dead Zone: Kuollut alue: Set the value of the dead zone for an axis. Aseta akselille kuolleen alueen arvo. Max Zone: Enimmäisalue: [NO KEY] [EI NAPPIA] Throttle setting that determines the behavior of how to interpret an axis hold or release. Kaasuasetus joka määrittää miten ennakoida pito tai vapautus akselilla. Negative Half Throttle Negatiivinen puolikaasutus Negative Throttle Negatiivinen kaasutus Normal Tavanomainen Positive Throttle Positiivinen kaasutus Positive Half Throttle Positiivinen puolikaasutus Haptic Trigger: Haptinen laukaisin: Current Value: Nykyinen arvo: Name: Nimi: Specify the name of an axis. Määritä akselille nimi. Mouse Settings Hiiriasetukset Set Aseta Set %1 Aseta %1 Left Mouse Button Hiiren vasen nappi Right Mouse Button Hiiren oikea nappi Click Napsautus Rigid Jäykkä Rigid Gradient Jäykkyyden kaltevuus Vibration Värinä ButtonEditDialog Dialog Ilmoite To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Tehdäksesi uuden määritteen, paina mitä tahansa näppäimistön näppäintä tai napsauta painiketta Näppäimistön tai Hiiren välilehdessä Placeholder Kannatin Enables a key press or release to only occur when a controller button is pressed. Kytkee päälle näppäinpainalluksen tai sen irtipäästön tapahtumaan vain silloin kun ohjaimen nappia painetaan. Toggle Kytke Enables rapid key presses and releases. Turbo controller. Kytkee päälle pikapainallukset ja irtipäästöt. Turbo-ohjain. Turbo Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Muistathan, että tämä ei toimi ellei sinulla ole tälläistä numeronäppäimistöä liitettynä tietokoneeseesi tai mikäli sellaista ei ole muun näppäimistön osana kuten työpöytä PC:iden tavanomaisissa näppäimistöissä yleensä on Attach the numeric keypad Liitä numeronäppäimistö Last keyboard/mouse button: Viimeisin näppäimistön/hiiren painike: Slots Määrityslokerot Na&me: Ni&mi: Specify the name of a button. Määritä painikkeelle nimi. Action: Toiminto: Specify the action that will be performed in game while this button is being used. Määritä toiminto joka pelaamisen aikana suoritetaan kun tätä painiketta käytetään. Advanced Edistyneemmät Choose your keyboard key Valitse näppäimistösi painike No button Ei painiketta Last button Viimeinen painike To change settings for last button, it must be at least one assignment from keyboard to gamepad Vaihtaaksesi asetuksia viimeisimmälle painikkeelle, tulee olla vähintään yksi toimitus näppäimistöltä peliohjaimelle To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad Vaihtaaksesi asetuksia turbon viimeisimmälle painikkeelle, tulee olla vähintään yksi toimitus näppäimistöltä peliohjaimelle No choice Ei valintaa Before you open window with advanced settings, you have to choice a key Ennen kuin avaat ikkunan edistyneempien asetusten suhteen, tulee sinun valita painike To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Avataksesi edistyneempien toimintojen ruudun, tulee kartoittaa ainakin yksi painike näppäimistöltä peliohjaimelle Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Määrityslokeroita ei saatu tälle napille tyhjennettyä, koska sille ei ollut yhtäkään määritystä asetettuna näppäimistöltä tai peliohjaimelta. Kartoita vähintään yksi painike näppäimistöltä peliohjaimelle As last gamepad button has been set Viimeinen peliohjainappi on asetettu Index %1 Hakemisto %1 Calibration Form Kaavake Input to calibrate: Syöte kalibrointiin: Steps Askeleet Z Z TextLabel TekstiTunnus X X gain vaikutus offset poikkeama Y Y Start calibration Aloita kalibrointi Close Sulje Reset settings Nollaa asetukset Save Tallenna Calibration Kalibrointi Gyroscope Gyroskooppi Accelerometer Kiihtyvyysmittari Selected device doesn't have any inputs to calibrate. Valitulla laitteella ei ole yhtäkään syöttötapaa joka kalibroida. Calibration was not saved for the preset. Do you really want to continue? Kalibrointia ei tallennettu oletukseksi. Haluatko todella jatkaa? Do you really want to reset calibration of current device? Haluatko todella nollata nykyisen laitteen kalibroinnin? Accelerometer calibration sets the neutral controller orientation. Kiihtyvyysanturin kalibrointi määrittää ohjaimen neutraalin suunnan. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Gyroskoopin kalibrointi korjaa anturin poikkeaman. Tämä estää osoittimen liikkeen ohjaimen ollessa levossa. Calibration completed. Kalibrointi valmis. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Poikkeaman kalibrointi suoritettu. Napsauta "jatka kalibrointia" jatkaaksesi vastekalibrointiin. Hold the controller in the desired neutral position and press continue. Pidä ohjain halutussa neutraaliasennossa ja paina jatka. Calibrating accelerometer Kiihtyvyysmittarin kalibrointi Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Kiihtyvyysmittarin tietojen kerääminen... Pidä ohjain paikallaan. Tämä voi kestää jopa %1 sekuntia. Place the controller at rest, e.g. put it on the desk, and press continue. Laita ohjain lepoon, esimerkiksi pöydälle, ja paina jatka. Calibrating gyroscope Kalibroidaan gyroskooppi Collecting gyroscope data... This can take up to %1 seconds. Kerätään gyroskoopista tietoja... Tämä voi kestää jopa %1 sekuntia. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Siirrä ohjainsauva nyt useita kertoja sen maksimiulottumaan eri suuntiin- ja anna palautua takaisin keskelle. Tämä voi kestää jopa %1 sekuntia. Calibrating stick Kalibroidaan ohjainsauvaa Continue calibration Jatka kalibrointia Now move the stick in full circles for several times. This can take up to %1 seconds. Liikuta nyt ohjainsauvaa useita kertoja ympyrää sen ulottuvuusreunoilla. Tämä voi kestää jopa %1 sekuntia. Calibration was saved for the preset. Do you really want to reset settings? Kalibraatio tallennettiin vakiolle. Haluatko varmasti nollata asetukset? CapturedWindowInfoDialog Captured Window Properties Kaapatut ikkuna-asetukset Information About Window Tiedot ikkunasta Class: Luokka: TextLabel TekstiTunnus Title: Nimike: Path: Polku: Match By Properties Täsmää asetusten kanssa Class Luokka Title Nimike Path Polku Full Path Täydellinen polku File Name Tiedostonimi DPadContextMenu Mouse (Normal) Hiiri (tavanomainen) Mouse (Inverted Horizontal) Hiiri (käänteinen vaakataso) Mouse (Inverted Vertical) Hiiri (käänteinen pystysuunta) Mouse (Inverted Horizontal + Vertical) Hiiri (käänteinen vaakataso + pystysuunta) Arrows Nuolet Keys: W | A | S | D Näppäimet: W | A | S | D NumPad Numeronäppäimistö None Ei mitään Standard Vakiollinen Eight Way Kahdeksansuuntainen 4 Way Cardinal 4-suuntainen kuten pääilmansuunnat 4 Way Diagonal 4-suuntainen viistosuunnissa Mouse Settings Hiiriasetukset DPadEditDialog Dialog Ilmoite Presets: Vakiot: Mouse (Normal) Hiiri (tavanomainen) Mouse (Inverted Horizontal) Hiiri (käänteinen vaakatasossa) Mouse (Inverted Vertical) Hiiri (käänteinen pystysuunnassa) Mouse (Inverted Horizontal + Vertical) Hiiri (käänteinen vaakatasossa + pystysuunnassa) Arrows Nuolet Keys: W | A | S | D Näppäimet: W | A | S | D NumPad Numeronäppäimistö None Ei mitään Dpad Mode: Dpadi-tila: Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Tavanomainen: 8-suuntainen dpadi jossa kaksisuuntapainikkeet ovat aktiivisena dpadin viistosuunta alueilla. Kahdeksansuunta: 8-alueinen dpad jossa jokaiselle suunnalle on oma painikkeensa. Vain yksi nappi on kerrallaan aktiivinen. Kätevä roguemaisissa, vuoropohjaisissa peleissä. 4 -pääilmansuunta: 4 -alueen dpadi jossa alueet vastaavat pääilmansuuntamallissa. Kätevä valikoissa. 4-suuntainen viistosuunnissa: 4 -alueen dpadi jokaisen alueen vastatessa viistosuuntaisesti. Standard Tavanomainen Eight Way Kahdeksansuunta 4 Way Cardinal 4-suuntainen kuten pääilmansuunnat 4 Way Diagonal 4-suuntainen viistosuunnissa DPad Delay: Dpadin viive: Time lapsed before a direction change is taken into effect. Kulunut aika ennen kuin suunnan muutos astuu voimaan. s s &Name: &Nimi: Specify the name of a dpad. Määritä dpadin nimi. Mouse Settings Hiiriasetukset Set Aseta Set %1 Aseta %1 EditAllDefaultAutoProfileDialog Default Profile Vakioprofiili Profile: Profiili: Browse Selaa Open Config Avaa asetusnäkymä Profile file path is invalid. Profiilin tiedostopolku on epäkelpo. ExtraProfileSettingsDialog Extra Profile Settings Lisäasetukset profiiliin Key Press Time: Painikkeen alhaallapitoaika: 0.00 ms 0.00 ms Profile Name: Profiilin nimi: s s GameController Game Controller Peliohjain GameControllerDPad DPad DPadi GameControllerMappingDialog Game Controller Mapping Peliohjainmääritykset <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> <html><head/><body><p>antimicrox käyttää SDL 2:n tarjoamaa <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> -rajapintaa soveltaakseen erilaisia gamepadeja yhtenäisesti toimivan vakiollisuuden piirissä. Jotta voit tehdä painikkeen määrityksen, korosta alla olevan painikerivin vastaavaa painikeriviä koskeva kartoitussolu. Voit sitten painaa painiketta tai siirtää akselia gamepadilla, solu päivittyy käytettävän fyysisen painikkeen tai akselin kanssa.</p><p>antimicrox käyttää määrittelemääsi kartoitusta tallentaakseen kartoitusmerkkijonon, joka ladataan SDL:ään.</p></body></html> A A B B X X Y Y Back Takaisin Start Start-aloita Guide Opas Left Shoulder Vasen olkapäänappi Right Shoulder Oikea olkapäänappi Left Stick Click Vasemman sauvan painallus Right Stick Click Oikean sauvan painallus Left Stick X Vasemman sauvan X Left Stick Y Vasemman sauvan Y Right Stick X Oikean sauvan X Right Stick Y Oikean sauvan Y Left Trigger Vasen liipaisin Right Trigger Oikea liipaisin DPad Up DPadi ylös DPad Left DPadi vasen DPad Down DPadi alas DPad Right DPadi oikea Mapping Määritys SDL 2 Game Controller Mapping String SDL 2 peliohjaimen kartoituslanka Last Axis Event: Viimeinen akselitapahtuma: Current Axis Detection Dead Zone: Nykyinen akselihavainnoinnin kuollut alue: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Peliohjainkartoitus (%1) (#%2) Discard Controller Mapping? Hylätäänkö ohjainkartoitus? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. Hylkää kartoitus tälle ohjaimelle? Mikäli toteutat hylkäyksen, palautetaan peliohjain sauvaohjaimeksi kun virkistät kaikki sauvaohjaimet. GameControllerSet Back Takaisin Guide Opas Start Aloita LS Click VO napsautus RS Click OO Napsautus L Shoulder V olkapääpainike R Shoulder O olkapää L Trigger V liipaisin R Trigger O liipaisin GameControllerTrigger Trigger Liipaisin JoyAccelerometerButton Up Ylös Down Alas Left Vasen Right Oikea Shock Isku JoyAccelerometerSensor Accelerometer Kiihtyvyysmittari JoyAxis Axis Akseli JoyAxisButton Button Painike Negative Negatiivi Positive Positiivinen Unknown Tuntematon JoyAxisContextMenu Mouse (Horizontal) Hiiri (vaakataso) Mouse (Inverted Horizontal) Hiiri (käänteinen vaakataso) Mouse (Vertical) Hiiri (pystysuunta) Mouse (Inverted Vertical) Hiiri (käänteinen pystysuunta) Arrows: Up | Down Nuolet: ylös | alas Arrows: Left | Right Nuolet: vasen | oikea Keys: W | S Näppäimet: W | S Keys: A | D Näppäimet: A | D NumPad: KP_8 | KP_2 Numeronäppäimistö: NP_8 | NP_2 NumPad: KP_4 | KP_6 Numeronäppäimistö: NP_4 | NP_6 None Ei mitään Mouse Settings Hiiriasetukset Left Mouse Button Hiiren vasen nappi Right Mouse Button Hiiren oikea nappi JoyButton Processing turbo for #%1 - %2 Käsitellään turbo kohteille #%1 - %2 Finishing turbo for button #%1 - %2 Viimeistellään turbo painikkeelle #%1 - %2 Distance change for button #%1 - %2 Etäisyyden muutos painikkeelle #%1 - %2 Button Painike [NO KEY] [EI NAPPIA] [Set %1 1W] [Aseta %1 1W] [Set %1 2W] [Aseta %1 2W] [Set %1 WH] [Aseta %1 WH] JoyButtonContextMenu Toggle Kytke Turbo Turbo Clear Tyhjää Set Select Aseta valintanappi Disabled Pois päältä Set %1 Aseta %1 Set %1 1W Aseta %1 1W Set %1 2W Aseta %1 2W Set %1 WH Aseta %1 WH JoyButtonSlot Mouse Hiiri Up Ylös Down Alas Left Vasen Right Oikea LB LB MB MB RB RB Pause Tauko Hold Pidä pohjassa Cycle Kierrätä Distance Etäisyys Release Irtipäästö Mouse Mod Hiiren muovaus Press Time Painalluksen aika Delay Viive Load %1 Lataa %1 Set Change %1 Aseta muutos %1 [Text] %1 [Teksti] %1 [Exec] %1 [Aja] %1 [NO KEY] [EI NAPPIA] JoyControlStick Stick Sauva JoyControlStickButton Up Ylös Right Oikea Down Alas Left Vasen Button Painike JoyControlStickContextMenu Mouse (Normal) Hiiri (tavanomainen) Mouse (Inverted Horizontal) Hiiri (käänteinen vaakataso) Mouse (Inverted Vertical) Hiiri (käänteinen pystysuunta) Mouse (Inverted Horizontal + Vertical) Hiiri (käänteinen vaakataso + pystysuunta) Arrows Nuolet Keys: W | A | S | D Näppäimet: W | A | S | D NumPad Numeronäppäimistö None Ei mitään Standard Tavanomainen Eight Way Kahdeksansuuntainen 4 Way Cardinal 4-suuntainen pääilmansuunnissa 4 Way Diagonal 4-suuntainen viistosuunnissa Mouse Settings Hiiriasetukset JoyControlStickEditDialog Dialog Ilmoite X: X: 0 0 Y: Y: Distance: Etäisyys: Bearing: Merkitys: % Safe Zone: % turva-alue: Presets: Vakiot: Mouse (Normal) Hiiri (tavanomainen) Mouse (Inverted Horizontal) Hiiri (käänteinen vaakataso) Mouse (Inverted Vertical) Hiiri (käänteinen pystysuuntainen) Mouse (Inverted Horizontal + Vertical) Hiiri (käänteinen vaakataso + pystysuuntainen) Arrows Nuolet Keys: W | A | S | D Näppäimet: W | A | S | D NumPad Numeronäppäimistö None Ei mitään Stick Mode: Sauvan toimintatapa: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Tavanomainen: 8-suuntainen sauva jossa kaksisuuntapainikkeet ovat aktiivisena kun sauva on viistosuunta-alueilla. Kahdeksansuunta: 8-alueinen sauva jossa jokaiselle suunnalle on oma painikkeensa. Vain yksi nappi on kerrallaan aktiivinen. Kätevä roguemaisissa, vuoropohjaisissa peleissä. 4 -pääilmansuunta: 4 -alueen sauva jossa alueet vastaavat pääilmansuuntamallissa. Kätevä valikoissa. 4-suuntainen viistosuunnissa: 4 -alueen sauva jokaisen alueen vastatessa viistosuuntaisesti. Standard Tavanomainen Eight Way Kahdeksansuuntainen 4 Way Cardinal 4-suuntainen - pääilmansuunnat 4 Way Diagonal 4-suuntainen viistosuunnat Dead Zone: Kuollut alue: Modifier Zone: Muunnosalue: Dead zone value to use for an analog stick. Kuolleen alueen arvo käytettäväksi analogiselle sauvaohjaimelle. Max Zone: Enimmäisalue: Value when an analog stick is considered moved 100%. Arvo kun analogisauvaa katsotaan liikutetuksi 100%. Diagonal Range: Viistottainen kantama: The area (in degrees) that each diagonal region occupies. Tontti (astekulman mukaan) jonka jokainen viistottainen alue varaa. Square Stick: Neliösauva: Percentage to modify a square stick coordinates to confine values to a circle Prosenttimääre muokata neliösauvan koordinaatteja jotka rajaantuvat ympyrämuodossa % % Stick Delay: Sauvan viive: Time lapsed before a direction change is taken into effect. Aika kunnes suunnanmuutos astuu voimaan. s s Modifier: Muovain: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Muokkauspainike joka on aktiivinen itse sauvan ollessa aktiivinen. Tämä painike on kätevä määrittääkseen alueita muovausnäppäimillä joita voidaan käyttää määräämään kävely/juoksu toiminto analogiseen sauvaan. PushButton TyöntöNappi Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Kynnysarvo, jolla muokkauspainike aktivoituu. Tämä painike on hyödyllinen määritettäessä vyöhykkeitä, joissa on muokkausavaimia, joita voidaan käyttää kävelyn/juoksun määrittelyyn analogiselle ohjaimelle. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Määrittää, aktivoituvatko muovainpainikkeet, kun ohjainsauva on kynnysarvon sisällä taikka ulkopuolella. Tämä painike on hyödyllinen määritettäessä vyöhykkeitä modifiointinäppäimille, joita voidaan käyttää kävely/juoksu -toiminnon määrittämiseen analogiselle tikulle. Invert Modifier Zone Käännä muovainalue päinvastaiseksi Na&me: Name: Ni&mi: Specify the name of an analog stick. Määritä analogisauvalle nimi. Mouse Settings Hiiriasetukset Set Aseta Set %1 Aseta %1 JoyControlStickModifierButton Modifier Muovain JoyDPad DPad DPadi JoyDPadButton Up Ylös Right Oikea Down Alas Left Vasen Button Painike JoyGyroscopeButton Pitch Up Nosta ylös Pitch Down Laske alas Yaw Left Siirrä vasemmalle Yaw Right Siirrä oikealle Roll Left Vieritä vasemmalle Roll Right Pyöritä oikealle JoyGyroscopeSensor Gyroscope Gyroskooppi JoySensorButton Button Painike JoySensorContextMenu Mouse Settings Hiiriasetukset JoySensorEditDialog Dialog Ilmoite 0 0 Acceleration (m/s^2): Kiihtyvyys (m/s^2): Pitch (°): Korkeus (°): Roll (°): Vieritys (°): % Safe Zone: % turva-alue: Presets: Vakiot: Dead Zone: Kuollut alue: Dead zone value to use for an analog sensor. Kuolleen alueen arvo analogiselle anturille. Max Zone: Enimmäisalue: Value when an analog sensor is considered moved 100%. Arvo kun analogianturin katsotaan liikkuneen 100%. Diagonal Range: Viistottaiskantama: The area (in degrees) that each diagonal region occupies. Alue (astekulman mukaan) jonka jokainen viistottainen alue varaa. Sensor Delay: Anturin viive: Time lapsed before a direction change is taken into effect. Kulunut aika ennen kuin suunnan muutos astuu voimaan. s s Na&me: Ni&mi: Specify the name of an analog sensor. Määritä analogiselle anturille nimi. Mouse Settings Hiiriasetukset Roll (°/s) Vieritä (°/s) Pitch (°/s) Nosta (°/s) Yaw (°/s) Siirrä (°/s) Set Aseta Set %1 Aseta %1 JoySensorPreset None Ei mitään Mouse (Normal) Hiiri (tavanomainen) Mouse (Inverted Horizontal) Hiiri (vaakatasossa käänteinen) Mouse (Inverted Vertical) Hiiri (pystysuunnassa käänteinen) Mouse (Inverted Horizontal + Vertical) Hiiri (käänteinen vaakatasossa + pystysuunnassa) Arrows Nuolet Keys: W | A | S | D Näppäimet: W | A | S | D NumPad Numeronäppäimistö JoyTabWidget <New> <Uusi> Battery level of controller Peliohjaimen paristovarauksen taso Remove Poista Remove configuration from recent list. Poista asetelma viimeksikäytettyjen luettelosta. Load Lataa Load configuration file. Lataa asetustiedosto. Save Tallenna Save changes to configuration file. Tallenna muutokset asetustiedostoon. Save As Tallenna nimellä Save changes to a new configuration file. Tallenna muutokset uuteen asetustiedostoon. Sets Määrityskokoomat Copy from Set Jäljennä määrityskokoomasta Settings Asetukset Set 1 Kokooma 1 Set 2 Kokooma 2 Set 3 Kokooma 3 Set 4 Kokooma 4 Set 5 Kokooma 5 Set 6 Kokooma 6 Set 7 Kokooma 7 Set 8 Kokooma 8 Stick/Pad Assign Sauvan/padin määritys Controller Mapping Ohjaimen kartoitus Quick Set Pika-asettelu Names Nimet Toggle button name displaying. Kytke napin nimi näkymään. Pref Aset Change global profile settings. Muuta yleismaailmallisia profiiliasetuksia. Reset Nollaa Revert changes to the configuration. Reload configuration file. Palauta asetusmuutokset alkutekijöihinsä. Uudelleenlataa asetustiedosto. Open Config Avaa asetukset Config Files (*.amgp *.xml) Asetustiedostot (*.amgp *.xml) Save Config Tallenna asetukset Config File (*.%1.amgp) Asetustiedosto (*.%1.amgp) Do you really want to reset buttons settings for joystick? Haluatko aivan varmasti nollata pelisauvan nappien asetukset? Set Aseta Save Profile Changes? Tallennetaanko profiilimuutokset? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Muutoksia uuteen profiiliin ei ole tallennettu. Haluatko tallentaa vaiko hylätä nykyisen profiilin? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Muutoksia profiiliin "%1" ei ole tallennettu. Haluatko tallentaa vaiko hylätä muutokset tähän nykyiseen profiiliin? Sticks Tattiohjaimet Sensors Anturit DPads D-padit No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Mitään nappeja ei ole määritetty. Käytäthän Pika-asetusta määrittääksesi näppäimet nappeihin tai piilottaaksesi tyhjät painikkeet. Set %1: %2 Aseta %1: %2 Set %1 Aseta %1 Copy Set Assignments Jäljennä asetusmääritykset Are you sure you want to copy the assignments and device properties from %1? Oletko varma että haluat jäljentää määritykset ja laiteominaisuudet kohteesta %1? Joystick Joystick Sauvaohjain JoystickStatusWindow Properties Ominaisuudet Details Yksityiskohdat Name: Nimi: %1 %1 Number: Numero: Axes: Akselit: Buttons: Napit: Hats: Hattuohjaimet: Sensors: Anturit: Battery: Virtavaraus: Unknown Tuntematon GUID: GUID (yleismaaimallinen tunnistin): Game Controller: Peliohjain: Axes Akselit Buttons Napit Hats Hattuohjaimet Sensors Anturit %1 (#%2) Properties %1 (#%2) Ominaisuudet Empty Tyhjä Low Matala Medium Keskitaso Full Täysi Wired Langallinen Different: %1 Erilainen: %1 Accelerometer + Gyroscope Kiihdytysmittari + gyroskooppi Accelerometer Kiihdytysmittari Gyroscope Gyroskooppi None Ei mitään Axis %1 Akseli %1 Hat %1 Hattuohjain %1 No Ei Yes Kyllä MainSettingsDialog Edit Settings Muokkaa asetuksia General Yleiset Controller Mappings Ohjaimen kartoitukset Language Kieli Auto Profile Automaattiprofiili Mouse Hiiri Advanced Edistyneet Pro&file Directory: Pro&fiili hakemisto: <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Määritä ohjelmalle vakiokansio jota käytetään tiedostoilmoituksissa ladatessa profiilia tai tallennettaessa uutta profiilia.</p></body></html> Recent Profile Count: Viimeaikaisten profiilien lukumäärä: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Profiililukumäärä joka voidaan osoittaa viimeaikaisten profiilien luetteloon. 0 johtaa siihen että näkyvää lukumäärärajaa ei tule olemaan.</p></body></html> Gamepad Poll Rate: Peliohjaimen kiertokyselyn tiheys: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Muuta kiertokyselytiheyttä jota ohjelma käyttää löytääkseen uusia tapahtumia ohjaimilta. Vakio on 10 ms. Mikäli vähennät tätä määrettä, johtaa se siihen että sovellus käyttää enemmän suoritintehoa joten testaathan käyttämäsi asetuksen ennen kuin käytät AntiMicroX:ää valvomatta. Hide main window when the main window close button is clicked instead of quitting the program. Piilota pääikkuna kun pääikkunan sulje-painiketta napsautetaan sen sijasta että ohjelma suljettaisiin. Close To Tray Sulje ohjelmapalkin ilmaisinalueelle Have Windows start AntiMicroX at system startup. Aseta Linux ajamaan AntiMicroX järjestelmäkäynnistyksen yhteydessä. Launch At Windows Startup Aja Linuxin käynnistyessä Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Näytä viimeaikaiset profiilit kaikille ohjaimille yhtenäisen luettelon muodossa telakkavalikossa. Alivalikoita ovat käytössä vakiollisesti. Single Profile List in Tray Yksittäinen profiililuettelo telakassa Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Pienennä sovellus tehtäväpalkkiin. Vakiollisesti, sovellus lasketaan järjestelmäpalkkiin mikäli tarjolla. Minimize to Taskbar Pienennä tehtäväpalkkiin This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Tämä vaihtoehto laittaa sovelluksen piilottamaan kaikki napit joilla ei ole lokeroita määritettynä. Pika-asetusen ilmaisinikkunaa tulee käyttää mikäli halutaan kutsua muokkaustila tai jos halutaan muokata ohjaimen nappeja. Hide Empty Buttons Piilota tyhjät napit When the program is launched, open the last known profile that was opened during the previous session. Kun sovellus käynnistetään, avaa viimeisin tunnettu profiili joka avattiin edellisen istunnon aikana. Auto Load Last Opened Profile Lataa viimeisin avattu profiili automaattisesti Only show the system tray icon when the program first launches. Näytä ainoastaan ilmoitusalueen kuvake kun sovellus käynnistyy ensi kerran. Launch in Tray Käynnistä palkkiin ilmoitusalueelle Associate .amgp files with AntiMicroX in Windows Explorer. Yhteensovita .amgp tiedostot AntiMicroX:n kanssa tiedostonhallintaan. Associate Profiles Yhdistä profiilit Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Muistathan, että tämä ei tule toimimaan ellei sinulla ole vastaavaa numeronäppäimistöä tietokoneessasi tai mikäli sitä ei ole sulautettuna vakiollisesti kuten työpöytätietokoneissa Attach the numeric keypad Liitä numeronäppäimistö Show low battery notification Näytä alhaisen paristovarauksen ilmoite Show empty battery notification Näytä ilmoite tyhjistä paristoista Key Repeat Näppäintoisto Active keys will be repeatedly pressed when this option is enabled. Toimeliaita näppäimiä painatetaan jatkuvasti tämän asetuksen ollessa kytkettynä. Enable Kytke päälle Delay: Viive: Specifies how much time should elapse before key repeating begins. Määrittää aikavasteen ennen kuin painallusten toisto aloitetaan. ms ms Rate: Vauhtivaste: Specifies how many times key presses will be performed per seconds. Määrittää montako näppäinpainallusta toteutetaan joka sekunti. times/s kertaa/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. Alla on luettelo itsemääritetyistä kartoituksista jotka on tallennettu. Voit käyttää seuraavaa taulukkoa poistaaksesi kartoitukset tai ottaa kartoitukset tilapäisesti pois päältä. Voit myös kytkeä pois kartoitukset jotka ovat sisällytetyt SDL:n kera; syötä vain uusi rivi asianmukaisen yleismaailmallisen pelisauvatunnisteen (GUID) tiimoilla ja ruksaa poiskytkentä. Asetukset eivät tule voimaan ennenkuin joko virkistät kaikki peliohjainsauvat tai nyppäät tuon kyseisen sauvan irti. GUID GUID (yleismaailmallinen tunnistin) Mapping String Kartoitusketju Disable? Kytketäänkö pois? Add Lisää Delete Poista <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntiMicroX on käännetty useille eri kielille kaikkien heidän toimesta jotka ovat halunneet kantaa kortensa kekoon. Sovellus valitsee vakiollisesti sopivan käännöksen joka vastaa järjestelmäsi kotoistusasetusta. Voit kuitenkin asettaa AntiMicroX:n lataamaan eri käännöksen riippuen mitä valitset luettelosta alla.</p></body></html> Default Vakio Português do Brasil Brasilian portugali English Englanti Français Ranska Deutsch Saksa Italiano Italia 日本語 Kiina Русский Venäjä српски / srpski Makedonia / serbia 简体中文 Yksinkertaistettu kiina Español Espanja українська Kreikka Polski Puola Active Toiminnassa Devices: Laitteet: All Kaikki Device Laite Profile Profiili Class Luokka Title Nimike Program Ohjelma Default? Vakio? Edit Muokkaa Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Ota pois päältä "Ehostettu osoitintarkkuus" -ikkuna-asetus AntiMicroX:ää ajettaessa. Kun kytket pois "Ehostetun osoitintarkkuuden" sallii se hiiren liikkeen AntiMicroX:n sisällä tarkemmin. Disable Enhance Pointer Precision Kytke Ehostettu osoitintarkkuus pois päältä Smoothing Siloitus History Si&ze: Menneiden tapahtumien Ko&ko: Weight Modi&fier: Painon Muo&kkaus: Refresh Rate: Virkistystaajuus: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Virkistystaajuus merkitsee aikamäärettä joka käytetään hiiritapahtumien välillä. Olethan valppaana kun muokkaat tätä asetusta koska se aiheuttaa lisääntynyttä suoritinkäyttöä. Liian alhaiseksi asetettu määre voi aiheuttaa epävakautta järjestelmään. Testaathan tätä asetusta ennen sen käyttöä. Spring Ponnahdus Screen: Näyttö: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Hyödynnä määritettyä näyttöä ponnahtelutilaa varten. Linuxissa, vakiona on käyttää päänäyttöä. Windowsissa, vakio on käyttää kaikkia käytettävissä olevia näyttöjä. Accel Numerator: Kiihdytyksen luvullinen osoittaja: 0 0 Accel Denominator: Kiihdytyksen luvullinen alentaja: Accel Threshold: Kiihdytyskynnys: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Mikäli kiihdytysarvot virtuaalihiirelle ovat muutetut erillisen prosessin johdosta, varsinkin lopettaessa vanhempaa peliä, tässä tapauksessa halunnet nollata kiihdytysarvot joita virtuaalihiiri käyttää. Reset Acceleration Kiihdytyksen nollaus Log File: Ylöskirjausten tiedosto: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> <html><head/><body><p><span style=" font-style:italic;">Huom. Määrittämätön lokitiedosto sallii kirjaukset päätteen tuotoksiin</span></p></body></html> Log Level: Ylöskirjaustaso: None Ei mitään Error Virhe Warning Varoitus Info Tiedot Verbose Sanallisesti Debug Virheenseuranta Note: To see the change of log level in console output (not in log file), application restart is required Huomautus: nähdäksesi ylöskirjaustason muutoksen päätteen tulosteessa (ei siis ylöskirjaustiedostossa), sovelluksen uudelleenkäynnistys vaaditaan Reset Nollaus AutoProfile (disabled in Wayland) Automaattiprofiili (poiskytketty Wayland-käytössä) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Myöskin, Windows-käyttäjät jotka haluavat hyödyntää matalampaa arvoa, heidän tulisi ruksata "Kytke Pois Osoitintarkkuus" ruksauslaatikko ellet ole kytkenyt pois tuota vaihtoehtoa Windowsissa. Select Default Profile Directory Valitse vakiollinen profiilihakemisto Are you sure you want to delete the profile? Oletko varma että haluat poistaa tämän profiilin? Save Log File As Tallenna ylöskirjaustiedosto nimellä Log Files (*.log) Ylöskirjaustiedostot (*.log) Do you really want to reset setting? Haluatko todella nollata asetuksen? Would you like to reset mappings too? Haluatko nollata myös kartoitusasetukset? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu Yhtäkään peliohjainsauvaa ei löytynyt. Kytke sellainen kiinni jonka jälkeen valitse "Päivitä sauvaohjaimet" valinta päävalikosta If events are not seen by a game, please click here to run this application as Administrator. Mikäli peli ei näe tapahtumia, napsautathan tässä ajaaksesi tämän sovelluksen Pääkäyttäjänä. Update Button Päivityspainike &App &Sovellus &Options &Vaihtoehdot He&lp Ap&u &Quit &Lopeta Ctrl+Q Ctrl+Q &Update Joysticks &Päivitä peliohjainsauvat Ctrl+U Ctrl+U &Hide &Piilota Ctrl+H Ctrl+H &About &Tietoja Ctrl+A Ctrl+A About &Qt Tietoja &Qt Ctrl+T Ctrl+T &Properties &Asetukset Ctrl+P Ctrl+P &Key Checker &Näppäintarkistin Ctrl+K Ctrl+K Home Page Kotisivu &GitHub Page &GitHub-sivu Ctrl+G Ctrl+G S&ettings A&setukset Ctrl+S Ctrl+S &Stick/Pad Assign &Sauva/padi-ohjainmääritys Ctrl+X Ctrl+X &Wiki &Wiki-tietokanta Ctrl+W Ctrl+W &Issues &Ongelmat Ctrl+I Ctrl+I &Calibration &Kalibrointi Ctrl+C Ctrl+C (%1) (%1) &Restore &Palauta Open File Avaa tiedosto Calibration couldn't be opened Kalibraatiota ei saatu avattua You must connect at least one controller to open the window Yhdistä vähintään yhteen ohjaimeen avataksesi ikkunan Run as Administrator? Ajetaanko Ylläpitäjänä? Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. Oletko varma, että haluat suorittaa tämän ohjelman järjestelmänvalvojana? Joidenkin pelien tapauksessa järjestelmänvalvojan oikeuksilla ajaminen estää AntiMicrossa luotujen asetusten käytön kyseisissä peleissä, ellei myös itse AntiMicroa suoriteta järjestelmänvalvojan oikeuksin. Tämä johtuu Windowsin (Vista ja uudemmat) käyttöoikeusongelmista, User Account Control (UAC). Failed to elevate program Ohjelman ajo ylennetyssä lupatilassa epäonnistui Failed to restart this program as the Administrator Ohjelman uudelleenkäynnistys Ylläpitäjänä epäonnistui %1 battery %1 akku Battery level is less than %1 Virtavaraus on vähemmän kuin %1 Device number: %1 Device name: %2 Laitenumero: %1 Laitenimi: %2 Update to %1 available Päivitys kohteelle %1 saatavilla Reading old profile Luetaan vanhaa profiilia This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 Tämä profiili käyttää ohjaimen GUID-numeroita (valmistajatunniste). Haluatko vaihtaa nämä GUID-numerot UniqueID-muotoon (yksilöllinen tunniste) tämän tiedoston kohdalla? Täten voit käyttää samaa mallia yhtenevien peliohjainten kanssa. Näin vanhaa tiedostoa ei voida ladata AntiMicro:ssa version 2.25 jälkeen. MouseAxisSettingsDialog Mouse Settings - Hiiren asetukset - Set %1 Aseta %1 MouseButtonSettingsDialog Mouse Settings - Hiiren asetukset - Set %1 Aseta %1 MouseControlStickSettingsDialog Mouse Settings Hiiriasetukset Set %1 Aseta %1 MouseDPadSettingsDialog Mouse Settings Hiiriasetukset Set %1 Aseta %1 MouseSensorSettingsDialog Mouse Settings Hiiriasetukset Set %1 Aseta %1 MouseSettingsDialog Mouse Settings Hiiriasetukset Mouse Mode: Hiiren tila: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Kohdistintilaa käytetään hiiren kohdistimen siirtämiseen näytöllä suhteessa sen nykyiseen sijaintiin riippuen siitä, kuinka paljon sitä akselilla liikutat tai nappia painettaessa. Spring-tilaa käytetään hiiren kohdistimen siirtämiseen näytön keskeltä riippuen siitä, miten paljon akselilla liikutaan. Hiiren kohdistin palaa näytön keskelle, kun akselialueella siirrytään takaisin kuolleelle alueelle. Cursor Kohdistin Spring Ponnahdus Acceleration: Kiihdytys: Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Parannettu: kolmiportainen käyrä, joka saa hiiren liikkumaan hitaasti akselin alapäässä ja nopeasti yläpäässä. Suoraviivainen: hiiri liikkuu suhteessa akseliin. Neliömallinen: Hiiri kiihtyy hitaasti alapäässä. Kuutiomallinen: Hiiri kiihtyy hitaammin kuin neliömallissa. Neliömalli tehostettuna: nostaa hiiren nopeutta 1,5 kertaiseksi kun 95% akselimatkasta on tehty. Tehotoiminto: mahdollistaa mukautetun käyrävaihtoehdon. Rauhallinen neliömallinen: kiihtyy akselin yläpäätä kohti vähitellen käyttäen neliökäyrämallia. Keveä kuutiomalli: kiihtyy vähitellen akselin yläpäätä kohti käyttäen kuutiokäyrämallia. Enhanced Precision Parannettu tarkkuus Linear Suoraviivainen Quadratic Neliömallinen Cubic Kuutiomallinen Quadratic Extreme Tehostettu neliömallinen Power Function Tehotoiminto Easing Quadratic Rauhallinen neliömalli Easing Cubic Rauhallinen kuutiomallinen Mouse Speed Settings Hiiren nopeusasetukset Enable to change the horizontal and vertical speed boxes at the same time. Ota käyttöön nopeuden samanaikainen muuttaminen vaaka- ja pystysuorassa. Change Together Muuta yhdessä Hori&zontal Speed: Vaaka&taso Nopeus: 1 = 20 pps 1 = 20 pikseliä / sek &Vertical Speed: &Pystysuunta Nopeus: Wheel Hori. Speed: Hiirirulla vaakat. Nopeus: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Aseta haluttu nopeus hiiren liikkeelle vaakatasossa simuloitujen pykälien määrän mukaan / sekunnissa. 1 = 1 notch(es)/s 1 = 1 pykälä(ä)/s Wheel Vert. Speed: Hiiren rulla / pysty. Nopeus: Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. s s Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier % % Mi&n Threshold: Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: X: 0 (0 pps) Y: Y: %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Tauko Prev Next Mail Home Media Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Last button Viimeinen painike There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set Pika-asettelu <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Aseta %1: %2 Set %1 Aseta %1 SetNamesDialog Set Name Settings Set 1 Asetelma 1 Set 2 Asetelma 2 Set 3 Asetelma 3 Set 4 Asetelma 4 Set 5 Asetelma 5 Set 6 Asetelma 6 Set 7 Asetelma 7 Set 8 Asetelma 8 Name SimpleKeyGrabberButton Mouse Hiiri SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Ylös Left Vasen Down Alas Right Oikea PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Tauko Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] [EI NAPPIA] UnixWindowInfoDialog Captured Window Properties Kaapatut ikkuna-asetukset Information About Window Tietoja ikkunasta Class: Luokka: TextLabel TekstiTunnus Title: Nimike: Path: Polku: Match By Properties Täsmää asetusten kanssa Class Luokka Title Nimike Path Polku VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK * + Enter Del < : Super (L) Menu Up Ylös Down Alas Left Vasen Right Oikea VirtualKeyboardMouseWidget Keyboard Mouse Hiiri Left Mouse Vasen Up Mouse Ylös Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Alas Right Mouse Oikea Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse Mouse Settings Hiiriasetukset NONE [NO KEY] [EI NAPPIA] Last button Viimeinen painike Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Tälle painikkeelle ei saatu tyhjennettyä lokeroita, koska yhtäkään määritystä näppäimistöstä peliohjaimeen ei ole. Kartoita vähintään yksi painike näppäimistöltä peliohjaimelle Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel Peru WinExtras [NO KEY] [EI NAPPIA] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_fr.ts000066400000000000000000013656001471077622000274010ustar00rootroot00000000000000 AboutDialog About À propos Version Info Infos Changelog Journal des modifications Credits Crédits AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Développé à l'origine par Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Développé ensuite par le groupe AntiMicro à l'adresse https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Puis par juliagoda à l'adresse https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Maintenu maintenant à l'adresse https://github.com/AntiMicroX/antimicrox. </p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributeurs : </span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Traducteurs : </span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; — Brésilien Portugais</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx — Chinois</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; — Français</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; — Allemand</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob — Allemand</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya — Japonais</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; — Russe</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; — Serbe</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk — Ukrainien</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; — Espagnol</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA — wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com — Italien</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; — Polonais</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development À propos du développement "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Copyright : 2013 - 2022 License Licence Program Version %1 Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Programme compilé le %1 à %2 Built Against SDL %1 Running With SDL %1 Fonctionne avec SDL %1 Using Qt %1 Utilise Qt %1 Using Event Handler: %1 Utilise %1 comme gestionnaire d'événement AddEditAutoProfileDialog Auto Profile Dialog Dialogue de profil auto Browse Parcourir Window: Fenêtre : Select Window. Click on the appropriate application window and the application file path will be populated in the form. Sélectionner la fenêtre. Cliquer sur la fenêtre de l'application voulue et le champ du chemin de fichier sera complété. Detect Window Properties Détecter les propriétés de la fenêtre Pro&file: Pro&fil : &Class: &Classe : T&itle: T&itre : set partial title titre partiel Application: Application : Select Sélectionner De&vices: Pé&riphériques : Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Sélectionner ce profil pour être le profil par défaut d'un périphérique spécifié. La sélection sera utilisée au lieu de toutes les options de profil par défaut. Set as Default for Controller Définir comme Contrôleur par défaut A different profile is already selected as the default for this device. Un autre profil est déjà sélectionné comme étant par défaut pour ce périphérique. Current (%1) Actuel (%1) Open Config Charger un fichier de configuration Select Program Sélectionner le programme Programs (*.exe) Programmes (*.exe) Please use the main default profile selection. Veuillez utiliser la sélection du profil principal par défaut. Main Profile Profil principal Already selected Déjà sélectionné Chosen Profile Profil choisi The selection will be used instead of the all default profile option. La sélection sera utilisée au lieu de toutes les options de profils. Please select a window by using the mouse. Press Escape if you want to cancel. Sélectionnez une fenêtre à l'aide de la souris. Appuyez sur Échap pour annuler. Capture Application Window Capturer la fenêtre de l'application Could not obtain information for the selected window. Impossible d'obtenir les informations de la fenêtre sélectionnée. Application Capture Failed Capture d'application échouée Profile file path is invalid. Le chemin vers le profil est invalide. No window matching property was specified. Aucune propriété de correspondance de fenêtres n'a été spécifié. Program path is invalid or not executable. Le chemin du programme est invalide ou non exécutable. File is not an .exe file. Le fichier n'est pas un fichier .exe. No window matching property was selected. Aucune propriété de correspondance de fenêtres n'a été sélectionnée. AdvanceButtonDialog Advanced Avancé Assignments Assignations Toggle Maintient de la pression Turbo Turbo Set Selector Sélection de réglage Blank or KB/M Vide ou Clavier/Souris Hold Maintenir Pause Pause Cycle Cycle Distance Distance Insert Insérer Delete Supprimer Clear All Nettoyer Time: Temps : 0.01s 0,01s 0s 0s Insert a pause that occurs in between key presses. Insère une pause de la durée indiquée entre la pression des touches. Release Relâchement Insert a new blank slot. Insère un nouvel emplacement vide. Join Joindre Split Séparer Delete a slot. Supprime un emplacement. Clear all currently assigned slots. Nettoie tous les emplacements assignés. Specify the duration of an inserted Pause or Hold slot. Spécifie la durée de Pause ou de Maintien. 0m 0m &Mouse Speed Mod: &Modif de vitesse de la souris : Specify the range past an axis dead zone in which a sequence of actions will execute. Spécifie la distance par rapport à la zone morte pour exécuter la suite des actions. Distance: Distance : % % Mouse Mod Mode de la Souris Press Time Temps d'appui Delay Retard Execute Exécuter Load Charger Set Change Changement de Configuration Text Entry Entrée de texte Placeholder Espace réservé 0 0 Set the percentage that mouse speeds will be modified by. Régler toutes les vitesses de la souris avec le pourcentage spécifié. Auto Reset Cycle After Réinitialisation de cycle auto après seconds secondes Executable: Exécutable : ... ... Arguments: Arguments : Enabled Activé Mode: Mode : <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>Normal : Appuyez et relâchez un bouton en fonction du taux.</p><p>Gradient : Modifie le temps d'appui et de relâchement de bouton en fonction de la distance de déplacement d'un axe. Le taux restera inchangé.</p><p>Pulse : Modifie combien de fois un bouton est appuyé et relâché par secondes. Le temps d'appui restera inchangé.</p></body></html> Normal Normal Gradient Gradient Pulse Impulsions Delay: Intervalle : 0.10s 0,10s Rate: Taux : 10.0/s 10,0/s Disabled Désactivé Select Set 1 One Way Sélection de la configuration 1 : Unidirectionnel Select Set 1 Two Way Sélection de la configuration 1 : Bidirectionnel Select Set 1 While Held Sélection de la configuration 1 : Quand maintenu Select Set 2 One Way Sélection de la configuration 2 : Unidirectionnel Select Set 2 Two Way Sélection de la configuration 2 : Bidirectionnel Select Set 2 While Held Sélection de la configuration 2 : Quand maintenu Select Set 3 One Way Sélection de la configuration 3 : Unidirectionnel Select Set 3 Two Way Sélection de la configuration 3 : Bidirectionnel Select Set 3 While Held Sélection de la configuration 3 : Quand maintenu Select Set 4 One Way Sélection de la configuration 4 : Unidirectionnel Select Set 4 Two Way Sélection de la configuration 4 : Bidirectionnel Select Set 4 While Held Sélection de la configuration 4 : Quand maintenu Select Set 5 One Way Sélection de la configuration 5 : Unidirectionnel Select Set 5 Two Way Sélection de la configuration 5 : Bidirectionnel Select Set 5 While Held Sélection de la configuration 5 : Quand maintenu Select Set 6 One Way Sélection de la configuration 6 : Unidirectionnel Select Set 6 Two Way Sélection de la configuration 6 : Bidirectionnel Select Set 6 While Held Sélection de la configuration 6 : Quand maintenu Select Set 7 One Way Sélection de la configuration 7 : Unidirectionnel Select Set 7 Two Way Sélection de la configuration 7 : Bidirectionnel Select Set 7 While Held Sélection de la configuration 7 : Quand maintenu Select Set 8 One Way Sélection de la configuration 8 : Unidirectionnel Select Set 8 Two Way Sélection de la configuration 8 : Bidirectionnel Select Set 8 While Held Sélection de la configuration 8 : Quand maintenu [NO KEY] [AUCUNE TOUCHE] sec. sec. /sec. /sec. Not checked slots Emplacements non cochés To delete slots, you need to select at least one Pour supprimer des emplacements, vous devez en sélectionner au moins un To insert slots, you need to select at least one Pour insérer des emplacements, vous devez en sélectionner au moins un Unknown current slot Emplacement actuel inconnu Click on chosen slots before joining them Cliquez sur les emplacements choisis avant de les joindre Not enough slots Pas assez d'emplacements It's impossible to join slots. Add at least one other slot. Il est impossible de joindre les emplacements. Ajoutez au moins un autre emplacement. Not selected slots Aucun emplacement sélectionné It's impossible to join slots. Select at least two slots before joining them Il est impossible de joindre les emplacements. Sélectionnez au moins deux emplacements avant de les joindre Only keyboard slots Seulement des emplacements pour clavier It's only possible to join simple and mix keyboard slots Il n’est possible de joindre que des emplacements de clavier simples et mixtes It's impossible to split slots. Add at least one other slot. Il est impossible de séparer les emplacements. Ajoutez au moins un autre emplacement. Not selected slot Pas d'emplacements sélectionnés Select your slot before splitting. Sélectionnez votre emplacement avant de séparer. Too many mix slots Trop d'emplacements mixtes Select one mix slot. Sélectionnez un emplacement mixte. Only mix slots Emplacements mixtes seulement It's only possible to split mix slot. Il n'est possible que de séparer les emplacements mixtes. Empty execution path Chemin d’exécution vide Line for execution file path is empty. Fill the first line before you are going to add a slot. La ligne du fichier à exécuter est vide. Veuillez compléter ce champ pour pouvoir continuer. File doesn't exist Le fichier n'existe pas There is no such file locally, that could be executed. Check the file on your system Aucun fichier pouvant être exécuté n'a été trouvé. Veuillez vérifier son emplacement Set %1 Configuration %1 Select Set %1 Sélectionner la configuration %1 One Way Unidirectionnel Two Way Bidirectionnel While Held Quand maintenu Choose Executable Choisir l'exécutable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. L'emplacement qui suit un emplacement Cycle sera exécuté au prochain appui de la touche. Plusieurs cycles peuvent être ajoutés afin de créer des séparations dans une séquence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Retarde par le temps spécifié le moment où l'emplacement suivant sera activé. L'emplacement activé précédant l'emplacement de retard sera actif même une fois la durée de retard passée. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Les emplacements qui suivent un emplacement Distance seront exécutés que lorsque l'axe est déplacé une certaine plage au-delà de la zone morte désignée. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. L'emplacement qui suit un emplacement Action sera exécuté si le bouton est maintenu au-delà de l'intervalle spécifié. Chose a profile to load when this slot is activated. Choisir un profil à charger quand cet emplacement est activé. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Cette action applique le pourcentage spécifié aux paramètres de vitesse de souris tant que l'emplacement est exécuté. Utile en cas d'un besoin momentané d'une sensibilité réduite. Specify the time that keys past this slot should be held down. Spécifie le temps de maintien de la touche située à l'emplacement suivant. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Insère une action de relâchement. L'emplacement suivant sera exécuté après le relâchement du bouton si le temps de maintien de celui-ci dépasse l'intervalle défini. Change to selected set once slot is activated. Basculer vers la configuration spécifiée quand l'emplacement est activé. Full string will be typed when a slot is activated. La chaîne de caractères sera tapée quand l'emplacement est activé. Execute program when slot is activated. Exécute le programme quand l'emplacement est activé. Choose Profile Choisir le profil Config Files (*.amgp *.xml) Fichiers de configuration (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Assignation du Joystick/Pad Sticks Joysticks DPads DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. Remarque : Cette fenêtre est destinée à assurer une rétrocompatibilité avec les profils créés avant Antimicro 2.0. Depuis la version 2.0, l'utilisation de la fenêtre "Mappage du contrôleur" est préférable. %1 (Joystick %2) %1 (Manette %2) Stick 1 Joystick 1 Enabled Activé Assign Assigner X Axis: Axe X : Y Axis: Axe Y : Stick 2 Stick 2 Number of Physical DPads: %1 Numéro du DPads Physique : %1 Virtual DPad 1 DPad Virtuel 1 Up: Haut : Down: Bas : Left: Gauche : Right: Droite : Axis %1 Axe %1 Axis %1 - Axe %1 - Axis %1 + Axe %1 + Button %1 Bouton %1 Move stick 1 along the X axis Déplacer le stick 1 selon l'axe X Move stick 1 along the Y axis Déplacer le stick 1 selon l'axe Y Move stick 2 along the X axis Déplacer le stick 2 selon l'axe X Move stick 2 along the Y axis Déplacer le stick 1 selon l'axe Y Press a button or move an axis Presser un bouton ou bouger un axe AxisEditDialog Axis Axe Mouse (Horizontal) Souris (Horizontal) Mouse (Inverted Horizontal) Souris (Horizontal Inversé) Mouse (Vertical) Souris (Vertical) Mouse (Inverted Vertical) Souris (Vertical Inversé) Arrows: Up | Down Flèches : Haut | Bas Arrows: Left | Right Flèches : Gauche | Droite Keys: W | S Touches : W | S Keys: A | D Touches : A | D NumPad: KP_8 | KP_2 Pavé Numérique : PN_8 | PN_2 NumPad: KP_4 | KP_6 Pavé Numérique : PN_4 | PN_6 None Aucun Set the value to use as the limit for an axis. Useful for a worn out analog stick. Définir la valeur à utiliser comme limite pour un axe. Utile pour un stick analogique usé. Negative Half Throttle Demie accélération négative Positive Half Throttle Demie accélération positive Haptic Trigger: Gâchette adaptative : Name: Nom : Specify the name of an axis. Indiquer le nom d'un axe. Mouse Settings Configurations de la Souris Set the value of the dead zone for an axis. Régler la valeur de la zone morte pour un axe. Presets: Pré-réglages : Dead Zone: Zone morte : Max Zone: Zone maximale : [NO KEY] [AUCUNE TOUCHE] Throttle setting that determines the behavior of how to interpret an axis hold or release. Configure l’accélération qui détermine le comportement de maintien ou de relâchement d'un axe. Negative Throttle Accélération négative Normal Normal Positive Throttle Accélération positive Current Value: Valeur actuelle : Set Configuration Set %1 Configuration %1 Left Mouse Button Bouton gauche de la souris Right Mouse Button Bouton droit de la souris Click Clic Rigid Rigide Rigid Gradient Dégradé rigide Vibration Vibration ButtonEditDialog Dialog Dialogue To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Pour assigner une touche à ce bouton, presser celle-ci ou cliquer sur son équivalent graphique dans les onglets clavier et souris Placeholder Espace réservé Toggle Pression continue Enables a key press or release to only occur when a controller button is pressed. Permet d'appuyer ou de relâcher une touche uniquement lorsqu'un bouton est pressé. Enables rapid key presses and releases. Turbo controller. Permet d'appuyer et de relâcher très rapidement une touche en maintenant pressé un bouton. Contrôle du Turbo. Turbo Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs N'oubliez pas que cela ne fonctionnera pas si le clavier n'est pas connecté à l'ordinateur ou s'il n'est pas intégré comme dans les ordinateurs de bureau. Attach the numeric keypad Ajouter le clavier numérique Last keyboard/mouse button: Dernière entrée clavier/souris : Slots Emplacements Na&me: No&m : Specify the name of a button. Indiquer le nom d'un bouton. Action: Action : Specify the action that will be performed in game while this button is being used. Indiquer l'action qui sera exécutée pendnt le jeu lorsque que ce bouton est utilisé. Advanced Avancé Choose your keyboard key Choisissez une touche clavier No button Aucun bouton Last button Dernier bouton To change settings for last button, it must be at least one assignment from keyboard to gamepad Pour changer les options du dernier bouton, il doit y avoir au moins une affectation du clavier au contrôleur To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad Pour changer les options de turbo du dernier bouton, il doit y avoir une assignation du clavier au contrôleur No choice Aucun choix Before you open window with advanced settings, you have to choice a key Avant d'ouvrir la fenêtre des options avancées, vous devez d'abord choisir une touche To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Pour ouvrir le mode avancé, il est nécessaire d'attribuer au moins un bouton du clavier au contrôleur Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Les emplacements pour les boutons n’ont pas pu être nettoyés, car il n’y avait pas de bouton défini du clavier pour le contrôleur. Mettez en correspondance au moins un bouton du clavier avec le contrôleur. As last gamepad button has been set Comme dernier bouton du contrôleur à avoir été défini Index %1 Index %1 Calibration Form Formulaire Input to calibrate: Interface à calibrer : Steps Étapes Z Z TextLabel Étiquette de texte X X gain gain offset décalage Y Y Start calibration Démarrer l'étalonnage Close Fermer Reset settings Réinitialiser les options Save Enregistrer Calibration Étalonnage Gyroscope Gyroscope Accelerometer Accéléromètre Selected device doesn't have any inputs to calibrate. L'appareil sélectionné n'a pas d'entrées à calibrer. Calibration was not saved for the preset. Do you really want to continue? Le calibrage n'a pas été sauvegardé pour le préréglage. Voulez-vous vraiment continuer ? Do you really want to reset calibration of current device? Souhaitez-vous vraiment réinitialiser l'étalonnage de l'appareil actuel ? Accelerometer calibration sets the neutral controller orientation. L'étalonnage de l'accéléromètre définit l'orientation neutre du contrôleur. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. L'étalonnage du gyroscope corrige le décalage du capteur. Cela permet d'éviter le déplacement du curseur lorsque le contrôleur est à l'arrêt. Calibration completed. L'étalonnage est terminé. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. L'étalonnage du décalage est terminé. Cliquez sur "Continuer l'étalonnage" pour poursuivre avec l'étalonnage du gain. Hold the controller in the desired neutral position and press continue. Maintenir le contrôleur dans la position neutre souhaitée et cliquez sur continuer. Calibrating accelerometer Étalonnage de l'accéléromètre Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Collecte des données de l'accéléromètre... Veuillez maintenir le contrôleur immobile. Cela peut prendre jusqu'à %1 secondes. Place the controller at rest, e.g. put it on the desk, and press continue. Placez la manette à l'arrêt, par exemple sur le bureau, et cliquez sur continuer. Calibrating gyroscope Étalonnage du gyroscope Collecting gyroscope data... This can take up to %1 seconds. Collecte des données du gyroscope... Cela peut prendre jusqu'à %1 secondes. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Déplacez ensuite le joystick plusieurs fois au maximum dans différentes directions, puis revenez au centre. Cela peut prendre jusqu'à %1 seconde. Calibrating stick Étalonnage du stick Continue calibration Poursuivre l'étalonnage Now move the stick in full circles for several times. This can take up to %1 seconds. Maintenant, déplacez le stick en faisant plusieurs fois des cercles complets. Cela peut prendre jusqu'à %1 secondes. Calibration was saved for the preset. Do you really want to reset settings? L'étalonnage a été enregistré pour le préréglage. Voulez-vous vraiment réinitialiser les paramètres ? CapturedWindowInfoDialog Captured Window Properties Propriétés de la fenêtre capturée Information About Window Informations sur la fenêtre Class: Classe : TextLabel Étiquette de texte Title: Titre : Path: Chemin : Match By Properties Correspondance par propriétés Class Classe Title Titre Path Chemin Full Path Chemin complet File Name Nom de fichier DPadContextMenu Mouse (Normal) Souris (Normal) Mouse (Inverted Horizontal) Souris (Horizontal Inversé) Mouse (Inverted Vertical) Souris (Vertical Inversé) Mouse (Inverted Horizontal + Vertical) Souris (Vertical et Horizontal Inversés) Arrows Flèches Keys: W | A | S | D Touches : W | A | S | D NumPad Pavé numérique None Aucun Standard Standard Eight Way 8 Voies 4 Way Cardinal 4 Voies cardinales 4 Way Diagonal 4 Voies diagonales Mouse Settings Configurations de la Souris DPadEditDialog Dialog Dialogue Presets: Pré-réglages : Mouse (Normal) Souris (Normal) Mouse (Inverted Horizontal) Souris (Horizontal Inversé) Mouse (Inverted Vertical) Souris (Vertical Inversé) Mouse (Inverted Horizontal + Vertical) Souris (Vertical et Horizontal Inversés) Arrows Flèches Keys: W | A | S | D Touches : W | A | S | D NumPad Pavé Numérique None Aucun Dpad Mode: Mode Dpad : &Name: &Nom : 4 Way Cardinal 4 Voies cardinales 4 Way Diagonal 4 Voies diagonales DPad Delay: Retard DPad : Time lapsed before a direction change is taken into effect. Temps écoulé avant qu'un changement de direction ne soit pris en compte. s s Specify the name of a dpad. Indiquer le nom d'un dpad. Mouse Settings Configurations de la Souris Standard Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Standard : DPad à 8 régions avec deux boutons de direction actifs lorsque le DPad se trouve dans une région diagonale. 8 Voies : DPad à 8 régions, chaque direction ayant son propre bouton dédié. Un seul bouton est actif à la fois. Utile pour les jeux de type rougelike. 4 Voies cardinales : DPad à 4 régions, les régions correspondant aux aux directions cardinales du DPad. Utile pour les menus. 4 Voies diagonales : DPad à 4 régions, chaque région correspondant à une zone diagonale. Eight Way 8 Voies Set Configuration Set %1 Configuration %1 EditAllDefaultAutoProfileDialog Default Profile Profil par défaut Profile: Profil : Browse Parcourir Open Config Charger un fichier de configuration Profile file path is invalid. Le chemin vers le profil est invalide. ExtraProfileSettingsDialog Extra Profile Settings Configuration supplémentaire du profil Key Press Time: Durée de pression de touche : 0.00 ms 0.00 ms Profile Name: Nom du profil : s s GameController Game Controller Contrôleur de jeu GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping Mappage du contrôleur de jeu <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> <html><head/><body><p>AntimicroX utilise le <span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span> <a href="https://wiki.libsdl.org/CategoryGameController"></a>fourni par SDL 2 afin d'abstraire diverses manettes de jeu pour s'adapter à un standard unifié. Pour effectuer une assignation de bouton, veuillez sélectionner la case correspondante au bouton approprié, puis appuyez sur un bouton ou déplacez un axe sur votre manette et la case se mettra à jour avec le bouton ou l'axe qui sera utilisé.</p><p>AntimicroX utilisera l'assignation que vous avez spécifié pour enregistrer une chaîne d'assignation qui sera chargée dans SDL.</p></body></html> A B X Y Back Back Start Guide Left Shoulder Gâchette haute gauche Right Shoulder Gâchette haute droite Left Stick Click Clic Stick Gauche Right Stick Click Clic Stick Droite Left Stick X Stick Gauche X Left Stick Y Stick Gauche Y Right Stick X Stick Droit X Right Stick Y Stick Droit Y Left Trigger Gâchette gauche Right Trigger Gâchette droite DPad Up Flèche Haut DPad Left Flèche Gauche DPad Down Flèche Bas DPad Right Flèche Droite Mapping Mappage SDL 2 Game Controller Mapping String Chaîne de mappage de contrôleur SDL 2 Last Axis Event: Dernier événement d'axe : Current Axis Detection Dead Zone: Détection de zone morte de l'axe actuel : 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Mappage du contrôleur (%1) (#%2) Discard Controller Mapping? Désactivé la cartographie de contrôleur de jeu ? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. Annuler les changements de mappage de ce contrôleur ? S'il est annulé, le contrôleur redeviendra un joystick une fois tous les joysticks mis à jour. GameControllerSet Back Back Guide Guide Start Start LS Click Clic stick gauche RS Click Clic stick droit L Shoulder Gâchette haute gauche R Shoulder Gâchette haute droite L Trigger Gâchette gauche R Trigger Gâchette droite GameControllerTrigger Trigger Gachette JoyAccelerometerButton Up Haut Down Bas Left Gauche Right Droite Shock Secousse JoyAccelerometerSensor Accelerometer Accéléromètre JoyAxis Axis Axe JoyAxisButton Negative Négatif Positive Positif Unknown Inconnu Button Bouton JoyAxisContextMenu Mouse (Horizontal) Souris (Horizontal) Mouse (Inverted Horizontal) Souris (Horizontal Inversé) Mouse (Vertical) Souris (Vertical) Mouse (Inverted Vertical) Souris (Vertical Inversé) Arrows: Up | Down Flèches : Haut | Bas Arrows: Left | Right Flèches : Gauche | Droite Keys: W | S Touches : W | S Keys: A | D Touches : A | D NumPad: KP_8 | KP_2 Pavé Numérique : PN_8 | PN_2 NumPad: KP_4 | KP_6 Pavé Numérique : PN_4 | PN_6 None Aucun Mouse Settings Configurations de la Souris Left Mouse Button Bouton gauche de la souris Right Mouse Button Bouton droit de la souris JoyButton Processing turbo for #%1 - %2 Traitement du turbo pour #%1 - %2 Finishing turbo for button #%1 - %2 Fin du turbo pour le bouton #%1 - %2 Distance change for button #%1 - %2 Changement de distance pour le bouton #%1 - %2 Button Bouton [NO KEY] [AUCUNE TOUCHE] [Set %1 1W] [Config %1 Uni] [Set %1 2W] [Config %1 Bi] [Set %1 WH] [Config %1 QM] JoyButtonContextMenu Toggle Basculer Turbo Turbo Clear Nettoyer Set Select Définir une configuration Disabled Désactivé Set %1 Configuration %1 Set %1 1W Configuration %1 Unidirectionnel Set %1 2W Configuration %1 Bidirectionnel Set %1 WH Configuration %1 Quand maintenu JoyButtonSlot Mouse Souris Up Haut Down Bas Left Gauche Right Droite LB BG MB BC RB BD Pause Pause Hold Maintenir Cycle Cycle Distance Distance Release Relâchement Mouse Mod Mode de la Souris Press Time Durée d'appui Delay Retard Load %1 Charger %1 Set Change %1 Sélection configuration %1 [Text] %1 [Texte] %1 [Exec] %1 [Éxec] %1 [NO KEY] [AUCUNE TOUCHE] JoyControlStick Stick JoyControlStickButton Up Haut Down Bas Left Gauche Right Droite Button Bouton JoyControlStickContextMenu Mouse (Normal) Souris (Normal) Mouse (Inverted Horizontal) Souris (Horizontal Inversé) Mouse (Inverted Vertical) Souris (Vertical Inversé) Mouse (Inverted Horizontal + Vertical) Souris (Vertical et Horizontal Inversés) Arrows Flèches Keys: W | A | S | D Touches : W | A | S | D NumPad Pavé Numérique None Aucun Standard Standard Eight Way 8 Voies 4 Way Cardinal 4 Voies cardinales 4 Way Diagonal 4 Voies diagonales Mouse Settings Configurations de la Souris JoyControlStickEditDialog Dialog Dialogue X: X : 0 0 Y: Y : Distance: Distance : Presets: Pré-réglages : Mouse (Normal) Souris (Normal) Mouse (Inverted Horizontal) Souris (Horizontal Inversé) Mouse (Inverted Vertical) Souris (Vertical Inversé) Mouse (Inverted Horizontal + Vertical) Souris (Vertical et Horizontal Inversés) Arrows Flèches Keys: W | A | S | D Touches : W | A | S | D NumPad PavéNum None Aucun Stick Mode: Mode du Stick : Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Standard : DPad à 8 régions avec deux boutons de direction actifs lorsque le DPad se trouve dans une région diagonale. 8 Voies : DPad à 8 régions, chaque direction ayant son propre bouton dédié. Un seul bouton est actif à la fois. Utile pour les jeux de type rougelike. 4 Voies cardinales : DPad à 4 régions, les régions correspondant aux aux directions cardinales du DPad. Utile pour les menus. 4 Voies diagonales : DPad à 4 régions, chaque région correspondant à une zone diagonale. 4 Way Cardinal 4 Voies cardinales 4 Way Diagonal 4 Voies diagonales Modifier Zone: Zone de modification : Dead zone value to use for an analog stick. Valeur de la zone morte à utiliser pour un stick analogique. Value when an analog stick is considered moved 100%. Valeur pour laquelle un stick analogique est considéré comme déplacé à 100%. The area (in degrees) that each diagonal region occupies. Zone (en degrés) occupée par chaque région diagonale. Square Stick: Stick carré : Percentage to modify a square stick coordinates to confine values to a circle Pourcentage de modification des coordonnées d'un stick carré pour limiter les valeurs à un cercle % % Stick Delay: Retard de stick : Time lapsed before a direction change is taken into effect. Temps écoulé avant qu'un changement de direction ne soit pris en compte. s s Modifier: Modificateur : Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Touche qui sera active lorsque le stick le sera. Cette touche est utile pour assigner des zones avec touches de modification qui peuvent être utilisées pour attribuer une fonctionnalité marcher/courir à un stick analogique. PushButton Bouton poussoir Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Seuil à partir duquel la touche de modification est activée. Cette touche est utile pour assigner des zones avec touches de modification qui peuvent être utilisées pour attribuer une fonctionnalité marcher/courir à un stick analogique. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Définis si les touches de modification sont activées lorsque le stick est à l'intérieur ou à l'extérieur du seuil. Cette touche est utile pour assigner des zones avec touches de modification qui peuvent être utilisées pour attribuer une fonctionnalité marcher/courir à un stick analogique. Invert Modifier Zone Inverser la Zone de modification Na&me: Name: No&m : Specify the name of an analog stick. Indiquer le nom d'un stick analogue. Mouse Settings Configurations de la Souris Standard Standard Bearing: Angle : % Safe Zone: % Zone sûre : Eight Way 8 Voies Dead Zone: Zone morte : Max Zone: Zone maximale : Diagonal Range: Valleur de diagonale : Set Configuration Set %1 Configuration %1 JoyControlStickModifierButton Modifier Modificateur JoyDPad DPad JoyDPadButton Up Haut Down Bas Left Gauche Right Droite Button Bouton JoyGyroscopeButton Pitch Up Tangage Haut Pitch Down Tangage bas Yaw Left Lacet gauche Yaw Right Lacet droite Roll Left Roulis gauche Roll Right Roulis droite JoyGyroscopeSensor Gyroscope Gyroscope JoySensorButton Button Bouton JoySensorContextMenu Mouse Settings Configurations de la Souris JoySensorEditDialog Dialog Dialogue 0 0 Acceleration (m/s^2): Accélération (m/s^2) : Pitch (°): Tangage (°) : Roll (°): Roulis (°) : % Safe Zone: % Zone sûre : Presets: Pré-réglages : Dead Zone: Zone morte : Dead zone value to use for an analog sensor. Valeur de zone morte à utiliser pour un capteur analogique. Max Zone: Zone maximale : Value when an analog sensor is considered moved 100%. Valeur lorsqu'un capteur analogique est considéré comme déplacé à 100 %. Diagonal Range: Valeur de diagonale : The area (in degrees) that each diagonal region occupies. Zone (en degrés) occupée par chaque région diagonale. Sensor Delay: Retard du capteur : Time lapsed before a direction change is taken into effect. Temps écoulé avant qu'un changement de direction ne soit pris en compte. s s Na&me: No&m : Specify the name of an analog sensor. Définissez le nom d'un capteur analogique. Mouse Settings Configurations de la Souris Roll (°/s) Roulis (°/s) Pitch (°/s) Tangage (°/s) Yaw (°/s) Lacet (°/s) Set Configuration Set %1 Configuration %1 JoySensorPreset None Aucun Mouse (Normal) Souris (Normal) Mouse (Inverted Horizontal) Souris (Horizontal Inversé) Mouse (Inverted Vertical) Souris (Vertical Inversé) Mouse (Inverted Horizontal + Vertical) Souris (Vertical et Horizontal Inversés) Arrows Flèches Keys: W | A | S | D Touches : W | A | S | D NumPad Pavé numérique JoyTabWidget <New> <Nouveau> Battery level of controller Niveau de batterie du contrôleur Remove Supprimer Remove configuration from recent list. Supprimer la configuration depuis la liste des recents. Load Charger Load configuration file. Charger un fichier de configuration. Save Enregistrer Save changes to configuration file. Enregistrer les modifications dans le fichier de configuration. Save As Enregistrer Sous Save changes to a new configuration file. Enregistrer les modifications dans un nouveau fichier de configuration. Sets Configurations Copy from Set Copier depuis la configuration Settings Paramètres Set 1 Configuration 1 Set 2 Configuration 2 Set 3 Configuration 3 Set 4 Configuration 4 Set 5 Configuration 5 Set 6 Configuration 6 Set 7 Configuration 7 Set 8 Configuration 8 Stick/Pad Assign Assignation du Stick/Pad Controller Mapping Mappage du contrôleur Quick Set Configuration Rapide Names Noms Toggle button name displaying. Alterner nom du bouton d'affichage. Pref Préférences Change global profile settings. Changer les paramètres globaux du profil. Reset Réinitialiser Revert changes to the configuration. Reload configuration file. Annuler les changements de configuration. Recharger le fichier de configuration. Open Config Charger un fichier de configuration Config Files (*.amgp *.xml) Fichiers de profil (*.amgp *.xml) Config File (*.%1.amgp) Fichier de profil (*.%1.amgp) Do you really want to reset buttons settings for joystick? Voulez-vous vraiment réinitialiser les paramètres des boutons du joystick ? Save Profile Changes? Enregistrer les modifications du profil ? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Les modifications apportées au nouveau profil n'ont pas été enregistrées. Souhaitez-vous enregistrer ou annuler les modifications du profil actuel ? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Les modifications apportées au profil "%1" n'ont pas été enregistrées. Souhaitez-vous enregistrer ou annuler les modifications du profil actuel ? Sticks Joysticks Sensors Capteurs DPads DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Aucune touche n'a été assignée. Veuillez utiliser la Configuration Rapide pour assigner des touches aux boutons ou désactiver le masquage des boutons vides. Set %1: %2 Configuration %1 : %2 Set %1 Configuration %1 Copy Set Assignments Copier la configuration d'assignations Are you sure you want to copy the assignments and device properties from %1? Êtes-vous sûr de vouloir copier les assignations et les propriétés du périphérique depuis %1 ? Save Config Enregistrer le fichier de configuration Set Configuration Joystick Joystick Manette JoystickStatusWindow Properties Propriétés Details Détails Name: Nom : %1 %1 Number: Nombre : Axes: Axes : Buttons: Boutons : Hats: Hats : Sensors: Capteurs : Battery: Batterie : Unknown Inconnu GUID: GUID : Game Controller: Contrôleur de jeu : Axes Axes Buttons Boutons Hats Hats Sensors Capteurs %1 (#%2) Properties %1 (#%2) Propriétés Empty Vide Low Faible Medium Moyenne Full Pleine Wired Filaire Different: %1 Différent : %1 Accelerometer + Gyroscope Accéléromètre + Gyroscope Accelerometer Accéléromètre Gyroscope Gyroscope None Aucun Axis %1 Axe %1 Hat %1 Hat %1 No Non Yes Oui MainSettingsDialog Edit Settings Modifier les paramètres General Général Controller Mappings Mappage des contrôleurs Language Langue Auto Profile Profil automatique Mouse Souris Advanced Avancé <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Défini l'emplacement par défaut que le programme utilisera pour les dialogue de chargement ou d'enregistrement de profils.</p></body></html> Recent Profile Count: Nombre de profils récents : <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Nombre de profils pouvant être placés dans la liste des profils récents. "0" aura pour effet de ne pas appliquer de limite au nombre de profils affichés.</p></body></html> Gamepad Poll Rate: Taux d'interrogation du contrôleur : Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Changez le taux d'interrogation que le programme utilise pour découvrir de nouveaux événements provenant des contrôleurs. Par défaut à 10 ms. Réduire cette valeur peut avoir pour effet d'augmenter la charge processeur, donc testez ce paramètre avant d'utiliser AntiMicroX sans surveillance. Hide main window when the main window close button is clicked instead of quitting the program. Masquer la fenêtre principale lors du clic sur le bouton de fermeture au lieu de quitter le programme. Close To Tray Fermer dans la zone de notifications Have Windows start AntiMicroX at system startup. Demandez à Windows de lancer AntiMicroX au démarrage du système. Launch At Windows Startup Lancer au démarrage de Windows Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Affiche les profils récents de tous les contrôleurs sous la forme d'une liste unique dans le menu de la barre des tâches. Par défaut, les sous-menus sont utilisés. Single Profile List in Tray Liste de profils unique dans la barre de tâches Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimiser le programme dans la barre des tâches. Par défaut, le programme se réduit dans la barre des tâches si elle est disponible. Minimize to Taskbar Réduire dans la zone de notifications This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Cette option a pour effet de masquer tous les boutons auxquels aucune assignations n'ont été attribués. La fenêtre de dialogue de Configuration Rapide devra être utilisée pour faire apparaître la boîte de dialogue d'édition des boutons de manettes. Hide Empty Buttons Masquer les boutons vides When the program is launched, open the last known profile that was opened during the previous session. Ouvre le dernier profil connu qui a été ouvert lors de la session précédente au lancement du programme. Auto Load Last Opened Profile Charger automatiquement le dernier profil ouvert Only show the system tray icon when the program first launches. N'afficher que l'icône de la barre d'état système au premier lancement du programme. Launch in Tray Lancer dans la zone de notifications Associate .amgp files with AntiMicroX in Windows Explorer. Associez les fichiers .amgp à AntiMicroX dans l'Explorateur Windows. Associate Profiles Associer les profils Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs N'oubliez pas que cela ne fonctionnera pas si s'il n'y a pas de clavier intégré ou si aucun clavier n'est connecté à l'ordinateur Attach the numeric keypad Brancher un pavé numérique Show low battery notification Afficher une notification de batterie faible Show empty battery notification Afficher la notification de batterie vide Key Repeat Répétition de la touche Active keys will be repeatedly pressed when this option is enabled. Les touches actives seront pressées de manière répétée lorsque cette option est activée. Enable Activer Specifies how much time should elapse before key repeating begins. Spécifie le délai avant que la répétition des touches ne commence. Specifies how many times key presses will be performed per seconds. Spécifie le nombre de pressions de touche effectuées par seconde. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntimicroX a été traduit dans de nombreuses langues différentes par les contributeurs. Par défaut, le programme choisira la langue appropriée en fonction des paramètres régionaux de votre système. Cependant, vous pouvez toutefois changer celle-ci dans la liste ci-dessous pour qu'AntimicroX charge une langue différente.</p></body></html> Português do Brasil Português do Brasil Français Français Deutsch Deutsch Italiano Italiano 日本語 日本語 Русский Русский српски / srpski српски / srpski 简体中文 简体中文 Español Español українська українська Polski Polski History Si&ze: Taille d'historiq&ue : Weight Modi&fier: Modi&ficateur de poids : Log File: Fichier journal : <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> <html><head/><body><p><span style=" font-style:italic;">Note Un fichier journal non spécifié permet d'imprimer les logs dans la sortie de la console</span></p></body></html> Log Level: Niveau du journal : None Aucun Error Erreur Warning Avertissement Info Info Verbose Verbeux Debug Debug Note: To see the change of log level in console output (not in log file), application restart is required Note : Pour voir le changement de niveau du journal dans la sortie console (pas dans le fichier journal), le redémarrage de l'application est nécessaire Reset Réinitialiser Class Classe Title Titre Program Programme Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Désactivez le paramètre Windows "Améliorer la précision du pointeur" lorsque AntiMicroX est en cours d'exécution. La désactivation de cette option permettra à la souris de se déplacer avec plus de précision au sein d'AntiMicroX. Disable Enhance Pointer Precision Désactiver l'amélioration de la précision du pointeur Smoothing Lissage Refresh Rate: Taux de rafraîchissement : The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Le taux de rafraîchissement est le temps qui s'écoule entre les événements de la souris. Soyez prudent lorsque vous modifiez ce paramètre, car le programme utilisera davantage de CPU. Une valeur trop basse peut entraîner une instabilité du système. Vérifier ce réglage avant de l'utiliser sans surveillance. Spring Ressort Screen: Écran : Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Utilisez l'écran spécifié pour le mode ressort. Sous Linux, la valeur par défaut est l'écran principal. Sous Windows, la valeur par défaut est d'utiliser tous les écrans disponibles. Accel Numerator: Numérateur d'accélération : 0 0 Accel Denominator: Dénominateur d'accélération : Accel Threshold: Seuil d'accélération : If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Si les valeurs d'accélération de la souris virtuelle ont été modifiées par un processus différent, par exemple lors de la fermeture d'un ancien jeu, il vous faudra peut-être réinitialiser les valeurs d'accélération de la souris virtuelle. Reset Acceleration Réinitialiser l'accélération Delay: Intervalle : Pro&file Directory: Emp&lacement du profil : ms ms Rate: Taux : times/s fois/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. Voici une liste des cartographies personnalisées qui ont été enregistrées. Utiliser le tableau suivant pour supprimer les cartographies ou désactiver temporairement une cartographie. Il est également possible de désactiver les cartographies qui sont inclus avec SDL, il suffit d'insérer une nouvelle ligne avec le GUID du manette approprié et cocher la case désactiver. Les paramètres ne prennent effet que lors de la prochaine réactualisation des joysticks ou en débranchant la manette spécifique. GUID Mapping String Chaîne de mappage Disable? Désactiver ? Delete Supprimer Default Défaut English English Active Actif Devices: Périphériques : All Tout Device Périphérique Profile Profil Default? Défaut ? Add Ajouter Edit Éditer AutoProfile (disabled in Wayland) Profil auto (désactivé dans Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. De plus, les utilisateurs Windows souhaitant utiliser une valeur basse doivent également cocher la case «Désactiver l'amélioration de la précision du pointeur» si l'option n'est pas désactivée dans Windows. Select Default Profile Directory Sélectionner l'emplacement par défaut du profil Are you sure you want to delete the profile? Êtes-vous sûr de vouloir supprimer le profil ? Save Log File As Enregistrer le fichier journal sous Log Files (*.log) Fichiers journaux (*.log) Do you really want to reset setting? Voulez-vous vraiment réinitialiser les paramètres ? Would you like to reset mappings too? Voulez-vous également réinitialiser les mappages ? MainWindow No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu Aucune manette n'a été détéctée. Merci de brancher une manette et de choisir l'option "Mettre à jour les manettes" du menu principal If events are not seen by a game, please click here to run this application as Administrator. Si les événements ne sont pas vus par le jeu, veuillez cliquer ici pour exécuter cette application en tant qu'administrateur. Update Button Actualiser le bouton &App &Appli &Options &Options AntiMicroX AntiMicroX He&lp Ai&de &Quit &Quitter Ctrl+Q Ctrl+Q &Update Joysticks &Mettre à jour les manettes Ctrl+U Ctrl+U &Hide &Masquer Ctrl+H Ctrl+H &About &À propos Ctrl+A Ctrl+A About &Qt À propos de &Qt Ctrl+T Ctrl+T &Properties &Propriétés Ctrl+P Ctrl+P &Key Checker &Vérificateur de touche Ctrl+K Ctrl+K &GitHub Page &Page GitHub Ctrl+G Ctrl+G S&ettings P&aramètres Ctrl+S Ctrl+S &Stick/Pad Assign &Assignation du Stick/Pad Ctrl+X Ctrl+X &Wiki &Wiki Ctrl+W Ctrl+W &Issues &Problèmes Ctrl+I Ctrl+I &Calibration &Étalonnage Ctrl+C Ctrl+C Home Page Page d'accueil (%1) Open File Ouvrir fichier Run as Administrator? Exécuter en tant qu'administrateur ? Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. Êtes-vous sûr de vouloir exécuter ce programme en tant qu'administrateur ? Certains jeux s'exécutent en tant qu'administrateur, ce qui empêchera les événements générés par Antimicro d'être utilisés par ces jeux, à moins qu'Antimicro ne soit également exécuté en tant qu'administrateur. Cela est dû à des problèmes d'autorisation causés par le contrôle de compte d'utilisateur (UAC) dans Windows Vista et versions ultérieures. Failed to elevate program Échec de l'élévation du programme Failed to restart this program as the Administrator Impossible de redémarrer ce programme en tant qu'administrateur %1 battery %1 de batterie Battery level is less than %1 Le niveau de batterie est inférieur à %1 Device number: %1 Device name: %2 Numéro de périphérique : %1 Nom du périphérique : %2 Update to %1 available Mise à jour vers %1 disponible Reading old profile Lecture de l’ancien profil This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 Ce profil utilise les numéros GUID des contrôleurs. Souhaitez-vous remplacer les numéros GUID par UniqueID dans ce fichier pour les utiliser avec des manettes identiques ? Ce genre d'ancien fichier ne peut pas être chargé dans AntimicroX depuis la version 2.25 &Restore &Restaurer Calibration couldn't be opened L'étalonnage n'a pas pu être ouvert You must connect at least one controller to open the window Vous devez connecter au moins un contrôleur pour ouvrir la fenêtre MouseAxisSettingsDialog Mouse Settings - Configurations de la Souris - Set %1 Configuration %1 MouseButtonSettingsDialog Mouse Settings - Configurations de la Souris - Set %1 Configuration %1 MouseControlStickSettingsDialog Mouse Settings Configurations de la Souris Set %1 Configuration %1 MouseDPadSettingsDialog Mouse Settings Configurations de la Souris Set %1 Configuration %1 MouseSensorSettingsDialog Mouse Settings Configurations de la Souris Set %1 Configuration %1 MouseSettingsDialog Mouse Settings Configurations de la Souris Mouse Mode: Mode de la Souris : Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Le mode "curseur" est utilisé pour déplacer le curseur de la souris autour de l'écran par rapport à sa position actuelle en fonction de la pression d'un axe ou d'un bouton. Le mode "ressort" est utilisé pour déplacer la souris depuis le centre de l'écran en fonction de la pression d'un axe. Le curseur de la souris retourne au centre de l'écran quand l'axe est déplacé vers la zone morte. Cursor Curseur Spring Ressort Acceleration: Accélération : Enhanced Precision Précision améliorée Linear Linéaire Quadratic Quadratique Cubic Cubique Quadratic Extreme Quadratique Extrême Power Function Fonction Avancée Easing Quadratic Assouplissement quadratique Easing Cubic Assouplissement cubique Mouse Speed Settings Configurations de la Vitesse de la Souris Enable to change the horizontal and vertical speed boxes at the same time. Activer la modification simultanée des boîtes de vitesse horizontale et verticale. Change Together Modifier en même temps Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Options permettant d'ajouter de l'accélération au mouvement de la souris (d'avantage que ce que la courbe d'accélération produirait). L'accélération est ajoutée en fonction de la vitesse à laquelle un axe est déplacé en une mesure de manette. Cela permet de contourner certains problèmes liés à la plage d'entrée très limitée disponible avec les sticks analogiques usuels des manettes. Delta Acceleration Accélération Delta &Multiplier: &Multiplicateur : Mi&n Threshold: Seuil Mi&n : 1 = 20 pps 1 = 20 pps Wheel Hori. Speed: Molette Hori. Vitesse : Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Définir la vitesse utilisée pour le défilement horizontal de la molette de souris selon le nombre de crans simulés par seconde. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Définir la vitesse utilisée pour le défilement vertical de la molette de souris selon le nombre de crans simulés par seconde. Sensitivit&y: Sensibilit&é : For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Pour la courbe d'accélération "Fonction Avancée". Spécifie le facteur à utiliser pour la sensibilité de la courbe. Quand la valeur dépasse 1.0, le mouvement de la souris sera accéléré plus rapidement à l'extrémité inférieure de l'axe. Easing Duration: Durée d’assouplissement : s s Highest value to accelerate mouse movement by Valeur la plus élevée d'accélération du mouvement de la souris x x Start %: Démarrer % : Acceleration begins at this percentage of the base multiplier L'accélération commence à ce pourcentage du multiplicateur de base Minimum amount of axis travel required for acceleration to begin Déplacement minimum de l'axe pour commencer l'accélération Max Threshold: Seuil Max : Maximum axis travel before acceleration has reached the multiplier value Déplacement maximum de l'axe pour atteindre la valeur du multiplicateur E&xtra Duration: Durée s&upplémentaire : Curve: Courbe : Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Rayon de relâchement : Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Spécifie que la zone du ressort sera relative à la position de la souris définie par un ressort non relatif. Relative Relatif Mouse Status Statut de la souris X: X : 0 (0 pps) 0 (0 pps) Y: Y : 1 = 1 notch(es)/s 1 = 1 cran(s)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Amélioré : Courbe à trois niveaux qui permet à la souris de se déplacer lentement sur l'extrémité inférieure d'un axe et rapidement sur l'extrémité supérieure. Linéaire : La souris se déplace proportionnellement à l'axe. Quadratique : La souris accélère lentement sur l'extrémité inférieure. Cubique : La souris accélère plus lentement que "Quadratique". Quadratique Extrême : Augmente la vitesse de la souris de 1,5 fois dès que l'axe atteint 95 %. Fonction Avancée : Permet une option de courbe personnalisée. Assouplissement quadratique : l'extrémité supérieure de l'axe est progressivement accélérée sur une période à l'aide d'une courbe quadratique. Assouplissement cubique : l'extrémité supérieure de l'axe est progressivement accélérée sur une période à l'aide d'une courbe cubique. Hori&zontal Speed: Vitesse Hori&zontale : &Vertical Speed: Vitesse &Verticale : Wheel Vert. Speed: Molette Vert. Vitesse : Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. Défini le temps nécessaire (en secondes) pour accélérer complètement la souris une fois l'extrémité supérieure d'un axe atteinte. % % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Prolonger la durée d'application de l'accélération supplémentaire. Le déplacement de l'axe sera pris en compte. Une impulsion plus lente diminuera le temps réel d'application de l'accélération supplémentaire. Spring Settings Configuration du Ressort Spring Width: Largeur du Ressort : Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Modifie la largeur de la région dans laquelle le curseur peut se déplacer en mode "ressort". 0 utilise toute la largeur de l'écran. Spring Height: Hauteur du Ressort : Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. Modifie la hauteur de la région dans laquelle le curseur peut se déplacer en mode "ressort". 0 utilise toute la hauteur de l'écran. %n notch(es)/s %n cran/s %n crans/s QKeyDisplayDialog Key Checker Vérificateur de touche <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Gestionnaire d'événements : Native Key Value: Valeur native de la touche : 0x00000000 Qt Key Value: Valeur de la touche Qt : antimicro Key Value: Valeur de la clé AntiMicroX : QObject Super Super Menu Menu Mute Sourdine Vol+ Vol+ Vol- Vol- Play/Pause Lecture/Pause Play Lecture Pause Pause Prev Précédent Next Suivant Mail Courriel Home Accueil Media Média Search Recherche Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Vos paramètres d'origine (précédemment stockés dans %1) ont été copiés dans %2 Vous pouvez maintenant, si vous le souhaitez, supprimer le dossier d'origine ou le laisser tel quel. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Un problème est survenu lors de la migration des paramètres. Les configurations originales sont stockées dans %1 mais leur nouvel emplacement est : %2 Vous pouvez manuellement migrer en renommant l'ancien dossier et en renommant le fichier en "antimicrox_settings.ini". Quitting Program Fermeture du programme # of joysticks found: %1 Nbre de joysticks trouvés : %1 List Joysticks: Liste des joysticks : --------------- --------------- Joystick %1: Joystick %1 : Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button Dernier bouton There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Le profil "%1" n'est pas un fichier XML. Profile location %1 does not exist. Le profil "%1" est introuvable. Controller identifier is not a valid value. L'identifiant du contrôleur n'a pas une valeur valide. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. La version de xinput doit être au moins 2.0. Aucun changement d'accélération de la souris ne sera effectué. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set Configuration Rapide <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>Merci de presser un bouton ou de bouger un axe de %1 (<span style=" font-weight:600;">%2</span>).<br/>Une fenêtre de dialogue va apparaître<br/>pour permettre de faire une assignation.</p></body></html> Quick Set %1 Configuration Rapide %1 SetAxisThrottleDialog Throttle Change Modifier l'accélération The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? axes ou axe dans ce cas ? La configuration de l'accélération de l'axe %1 a été modifié. Faut-il appliquer cette valeur d'accélération à tous les réglages ? SetJoystick Set %1: %2 Configuration %1 : %2 Set %1 Configuration %1 SetNamesDialog Set Name Settings Set 1 Configuration 1 Set 2 Configuration 2 Set 3 Configuration 3 Set 4 Configuration 4 Set 5 Configuration 5 Set 6 Configuration 6 Set 7 Configuration 7 Set 8 Configuration 8 Name SimpleKeyGrabberButton Mouse Souris SpringModeRegionPreview Spring Mode Preview Aperçu du mode ressort UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 Utilisation du fichier de périphérique uinput %1 UInputHelper a q b b c c d d e e f f g g h h i i j j k k l l m , n n o o p p q a r r s s t t u u v v w z x x y y z w Esc Échap F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace Retour Arrière Tab Tabulation [ [ ] ] \ \ CapsLock VerrMaj ; ; ' ' Enter Entrée Shift_L Maj_G , , . . / / Ctrl_L Ctrl_G Super_L Super_G Alt_L Alt_L Space Espace Alt_R Alt_R Menu Menu Ctrl_R Ctrl_D Shift_R Maj_D Up Haut Left Gauche Down Bas Right Droite PrtSc ImpÉcr Ins Ins Del Suppr Home Début End Fin PgUp PgeSuiv PgDn PgePréc NumLock PavéNum * * + + KP_Enter PN_Entrée KP_1 PN_1 KP_2 PN_2 KP_3 PN_3 KP_4 PN_4 KP_5 PN_5 KP_6 PN_6 KP_7 PN_7 KP_8 PN_8 KP_9 PN_9 KP_0 PN_0 SCLK Arrêt Défil Pause Pause Super_R Super_D Mute Sourdine VolDn Vol- VolUp Vol+ Play Lire Stop Arrêter Prev Préc Next Suivant [NO KEY] [AUCUNE TOUCHE] UnixWindowInfoDialog Captured Window Properties Propriétés de la fenêtre capturée Information About Window Informations de la fenêtre Class: Classe : TextLabel Étiquette de texte Title: Titre : Path: Chemin : Match By Properties Correspondance par propriétés Class Classe Title Titre Path Chemin VDPad VDPad VirtualKeyPushButton Space Espace Tab Tab Shift (L) Maj (G) Shift (R) Maj (D) Ctrl (L) Ctrl (G) Ctrl (R) Ctrl (D) Alt (L) Alt (G) Alt (R) Alt (D) Alt Gr AltGr ` ~ - = [ ] \ Caps Verr Maj ; ' , . / ESC ECHAP PRTSC Impr Ecran SCLK Arrêt Defil INS INSER PGUP PGUP DEL SUPPR PGDN PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK VERR NUM * + Enter Entrée Del Suppr < : Super (L) Super (G) Menu Up Haut Down Bas Left Gauche Right Droite VirtualKeyboardMouseWidget Keyboard Clavier Mouse Souris Mouse Settings Configurations de la Souris Left Mouse Gauche Up Mouse Haut Left Button Mouse Bouton Gauche Middle Button Mouse Bouton Central Right Button Mouse Bouton Droit Wheel Up Mouse Molette haut Wheel Left Mouse Molette gauche Wheel Right Mouse Molette droite Wheel Down Mouse Molette bas Down Mouse Bas Right Mouse Droite Button 4 Mouse Bouton 4 Mouse 8 Mouse Bouton 8 Button 5 Mouse Bouton 5 Mouse 9 Mouse Bouton 9 NONE AUCUNE [NO KEY] [AUCUNE TOUCHE] Last button Dernier bouton Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Les emplacements pour les boutons n’ont pas pu être nettoyés, car il n’y avait pas de bouton défini du clavier pour le contrôleur. Mettez en correspondance au moins un bouton du clavier avec le contrôleur. Others Autres Applications Applications Browser Back Navigation - Retour Browser Favorites Navigation - Favoris Browser Forward Navigation - Suivant Browser Home Accueil navigateur Browser Refresh Navigation - Actualiser Browser Search Navigation - Rechercher Browser Stop Navigation - Arrêter Calc Calculatrice Email Courriel F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media Média Media Next Média - Suivant Media Play Média - Lecture Media Previous Média - Précédent Media Stop Média - Arrêt Search Recherche Volume Down Baisser volume Volume Mute Couper le son Volume Up Augmenter volume VirtualMousePushButton INVALID INVALIDE WinAppProfileTimerDialog Capture Application Capturer l'application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Après avoir appuyé sur le bouton "Capturer l'application", veuillez sélectionner la fenêtre de l'application à laquelle vous souhaitez associer un profil. L'application active sera capturée après le nombre de secondes défini. Timer: Minuteur : Seconds Secondes Cancel Annuler WinExtras [NO KEY] [AUCUNE TOUCHE] AntiMicro Profile X11Extras ESC Échap Tab Tab Space Espace DEL SUPPR Return Retour KP_Enter PN_Entrée Backspace Retour arrière Alt Gr AltGr xinput extension was not found. No mouse acceleration changes will occur. L'extension xinput n'a pas été trouvée. Aucun changement d'accélération de la souris ne sera effectué. xinput version must be at least 2.0. No mouse acceleration changes will occur. La version de xinput doit être au moins 2.0. Aucun changement d'accélération de la souris ne sera effectué. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. Impossible de mettre à jour le profil XML du fichier %1. XMLConfigWriter Could not write to profile at %1. Impossible d'écrire le profil %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Démarre le programme dans la zone de notification. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_hr.ts000066400000000000000000013057441471077622000274060ustar00rootroot00000000000000 AboutDialog About O Version Verzija Info Informacije Changelog Dnevnik promjena Credits Zasluge AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development O izradi "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Autorska prava: 2013 - 2022 {2013 ?} License Licenca Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 AddEditAutoProfileDialog Auto Profile Dialog Pro&file: Browse Window: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Detect Window Properties &Class: T&itle: set partial title Application: Select De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Set as Default for Controller A different profile is already selected as the default for this device. Current (%1) Open Config Select Program Programs (*.exe) Please use the main default profile selection. Main Profile Already selected Chosen Profile The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. Capture Application Window Could not obtain information for the selected window. Application Capture Failed Profile file path is invalid. No window matching property was specified. Program path is invalid or not executable. File is not an .exe file. No window matching property was selected. AdvanceButtonDialog Advanced Assignments Toggle Turbo Set Selector Blank or KB/M Hold Pause Cycle Distance Insert Delete Clear All Time: 0.01s 0s Insert a pause that occurs in between key presses. Release Insert a new blank slot. Delete a slot. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. 0m &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: % Mouse Mod Press Time Delay Execute Load Set Change Text Entry Join Split Placeholder 0 Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After seconds Executable: ... Arguments: Enabled Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Delay: 0.10s Rate: 10.0/s Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] sec. /sec. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: Y Axis: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Down: Left: Right: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Haptic Trigger: Name: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Dead Zone: Max Zone: [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Attach the numeric keypad Last keyboard/mouse button: Slots Na&me: Specify the name of a button. Action: Specify the action that will be performed in game while this button is being used. Advanced Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel TextLabel X X gain offset Y Y Start calibration Close Reset settings Save Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAccelerometerButton Up Up Down Down Left Left Right Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Negative Positive Unknown Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Up Down Left Right LB MB RB Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] JoyControlStick Stick JoyControlStickButton Up Down Left Right Button JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: 0 Y: Distance: Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Down Left Right Button JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Button JoySensorContextMenu Mouse Settings Mouse Settings JoySensorEditDialog Dialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Safe Zone: Presets: Presets: Dead Zone: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: Diagonal Range: The area (in degrees) that each diagonal region occupies. The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Na&me: Na&me: Specify the name of an analog sensor. Mouse Settings Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None None Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad JoyTabWidget <New> Battery level of controller Remove Remove configuration from recent list. Load Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sensors DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Details Name: %1 Number: Axes: Buttons: Hats: Sensors: Battery: Unknown GUID: Game Controller: Axes Buttons Hats Sensors %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None None Axis %1 Hat %1 No Yes MainSettingsDialog Edit Settings General Controller Mappings Language Auto Profile Mouse Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Pro&file Directory: Show low battery notification Show empty battery notification Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID Mapping String Disable? Delete Default English Active Devices: All Device Profile Default? Add Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Options He&lp &Quit Ctrl+Q &Update Joysticks Ctrl+U &Hide Ctrl+H &About Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page (%1) Open File Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Failed to elevate program Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSensorSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Prev Next Mail Home Media Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name SimpleKeyGrabberButton Mouse SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 2 3 4 5 6 7 8 9 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK * + Enter Del < : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard Mouse Mouse Settings Left Mouse Up Mouse Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel WinExtras [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_id.ts000066400000000000000000013227701471077622000273670ustar00rootroot00000000000000 AboutDialog About Tentang Version Versi Info Informasi Changelog Log perubahan Credits AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dimulai oleh Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Lalu dilanjutkan oleh grup AntiMicro di https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Lalu dilanjutkan lagi oleh juliagoda di https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">sekarang di lanjutkan dan di update oleh https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Penerjemah:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Bahasa Portugis Brazil</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Bahasa China</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - Bahasa Prancis</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - Bahasa Jerman</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - Bahasa Jerman</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Bahasa Jepang</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Bahasa Rusia</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Bahasa Serbia</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Bahasa Ukraina</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Bahasa Spanyol</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Bahasa Italia</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Bahasa Polandia</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Copyright: 2013 - 2022 {2013 ?} License Lisensi Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 AddEditAutoProfileDialog Auto Profile Dialog Pro&file: Browse Window: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Detect Window Properties &Class: T&itle: set partial title Application: Select De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Set as Default for Controller A different profile is already selected as the default for this device. Current (%1) Open Config Select Program Programs (*.exe) Please use the main default profile selection. Main Profile Already selected Chosen Profile The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. Capture Application Window Could not obtain information for the selected window. Application Capture Failed Profile file path is invalid. No window matching property was specified. Program path is invalid or not executable. File is not an .exe file. No window matching property was selected. AdvanceButtonDialog Advanced Assignments Toggle Turbo Set Selector Blank or KB/M Hold Pause Cycle Distance Insert Delete Clear All Time: 0.01s 0s Insert a pause that occurs in between key presses. Release Insert a new blank slot. Delete a slot. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. 0m &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: % Mouse Mod Press Time Delay Execute Load Set Change Text Entry Join Split Placeholder 0 Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After seconds Executable: ... Arguments: Enabled Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Delay: 0.10s Rate: 10.0/s Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] sec. /sec. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: Y Axis: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Down: Left: Right: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Haptic Trigger: Name: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Dead Zone: Max Zone: [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Attach the numeric keypad Last keyboard/mouse button: Slots Na&me: Specify the name of a button. Action: Specify the action that will be performed in game while this button is being used. Advanced Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel TextLabel X X gain offset Y Y Start calibration Close Reset settings Save Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAccelerometerButton Up Up Down Down Left Left Right Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Negative Positive Unknown Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Up Down Left Right LB MB RB Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] JoyControlStick Stick JoyControlStickButton Up Down Left Right Button JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: 0 Y: Distance: Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Down Left Right Button JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Button JoySensorContextMenu Mouse Settings Mouse Settings JoySensorEditDialog Dialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Safe Zone: Presets: Presets: Dead Zone: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: Diagonal Range: The area (in degrees) that each diagonal region occupies. The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Na&me: Na&me: Specify the name of an analog sensor. Mouse Settings Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None None Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad JoyTabWidget <New> Battery level of controller Remove Remove configuration from recent list. Load Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sensors DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Details Name: %1 Number: Axes: Buttons: Hats: Sensors: Battery: Unknown GUID: Game Controller: Axes Buttons Hats Sensors %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None None Axis %1 Hat %1 No Yes MainSettingsDialog Edit Settings General Controller Mappings Language Auto Profile Mouse Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Pro&file Directory: Show low battery notification Show empty battery notification Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID Mapping String Disable? Delete Default English Active Devices: All Device Profile Default? Add Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Options He&lp &Quit Ctrl+Q &Update Joysticks Ctrl+U &Hide Ctrl+H &About Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page (%1) Open File Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Failed to elevate program Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSensorSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Prev Next Mail Home Media Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name SimpleKeyGrabberButton Mouse SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 2 3 4 5 6 7 8 9 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK * + Enter Del < : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard Mouse Mouse Settings Left Mouse Up Mouse Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel WinExtras [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_it.ts000066400000000000000000013256161471077622000274110ustar00rootroot00000000000000 AboutDialog About A proposito Version Versione Info Info Changelog Changelog Credits Ringraziamenti AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development Informazioni sviluppo "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Copyright: 2013 - 2016 {2013 ?} {2022?} {2013 ?} License Licenza Program Version %1 Versione programma %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Programma compilato il %1 alle %2 Built Against SDL %1 Costruito con SDL %1 Running With SDL %1 Eseguito con SDL %1 Using Qt %1 Utilizzando Qt %1 Using Event Handler: %1 Gestore di eventi in uso: %1 AddEditAutoProfileDialog Auto Profile Dialog Finestra di auto-profilo Pro&file: Browse Sfoglia Window: Finestra: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Seleziona la finestra. Clicca la finestra giusta e il percorso al file dell'applicazione riempirà il campo. Detect Window Properties Rileva proprietà finestra &Class: T&itle: set partial title Application: Applicazione: Select Seleziona De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Seleziona questo profilo per renderlo il predefinito per il dispositivo specificato. La selezione verrà usata al posto di qualsiasi altro profilo predefinito. Set as Default for Controller Imposta come controller predefinito A different profile is already selected as the default for this device. È già stato selezionato un altro profilo come predefinito per questo dispositivo. Current (%1) Corrente (%1) Open Config Apri configurazione Select Program Seleziona programma Programs (*.exe) Programmi (*.exe) Please use the main default profile selection. Per favore usa la selezione profilo predefinita principale. Main Profile Profilo principale Already selected Già selezionato Chosen Profile Profilo selezionato The selection will be used instead of the all default profile option. La selezione verrà usata al posto del profilo predefinito. Please select a window by using the mouse. Press Escape if you want to cancel. Per favore seleziona una finestra utilizzando il mouse. Premi Esc se vuoi annullare. Capture Application Window Cattura finestra applicazione Could not obtain information for the selected window. Impossibile ottenere le informazioni della finestra selezionata. Application Capture Failed Cattura applicazione fallita Profile file path is invalid. Percorso del file di profilo invalida. No window matching property was specified. Non è stata specificata alcuna proprietà per identificare la finestra. Program path is invalid or not executable. Il programma è invalido o non è un eseguibile. File is not an .exe file. Il file non è un .exe. No window matching property was selected. Non è stata selezionata alcuna proprietà per identificare la finestra. AdvanceButtonDialog Advanced Avanzate Assignments Assegnazioni Toggle Cambio stato Turbo Turbo Set Selector Selezionatore set Blank or KB/M Vuoto o Tastiera/Mouse Hold Tieni Pause Pausa Cycle Ciclo Distance Distanza Insert Inserisci Delete Cancella Clear All Cancella tutto Time: Tempo: 0.01s 0.01s 0s 0s Insert a pause that occurs in between key presses. Inserisci una pausa tra un tasto e l'altro. Release Rilascia Insert a new blank slot. Inserisci un nuovo slot vuoto. Join Unisci Split Separa Delete a slot. Cancella uno slot. Clear all currently assigned slots. Cancella tutti gli slot assegnati. Specify the duration of an inserted Pause or Hold slot. Specifica la durata di una Pausa inserita o di un Tieni. 0m 0m &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Specifica l'intervallo dopo la zona morta di un'asse in cui una sequenza di azioni verrà eseguita. Distance: Distanza: % % Mouse Mod Modifica mouse Press Time Tempo di pressione Delay Ritardo Execute Esegui Load Carica Set Change Cambio di set Text Entry Inserimento testo Placeholder Segnaposto 0 0 Set the percentage that mouse speeds will be modified by. Imposta la percentuale con cui le velocità del mouse verranno modificate. Auto Reset Cycle After Auto-resetta ciclo dopo seconds secondi Executable: ... ... Arguments: Enabled Attivato Mode: Modalità: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>Normale: preme e rilascia ripetutamente un tasto a seconda del rapporto scelto.</p><p>Gradiente: modifica il tasto premuto e il ritardo di un tasto rilasciato a seconda di quanto è stata mossa un'asse. Il rapporto rimarrà lo stesso.</p><p>Pulsa: modifica quante volte un tasto viene premuto e rilasciato al secondo. Il ritardo del tasto rimarrà lo stesso.</p></body></html> Normal Normale Gradient Gradiente Pulse Pulsa Delay: Ritardo: 0.10s 0.10s Rate: Rapporto: 10.0/s 10.0/s Disabled Disattivato Select Set 1 One Way Selezione set 1 a una direzione Select Set 1 Two Way Selezione set 1 a due direzioni Select Set 1 While Held Selezione set 1 finché premuto Select Set 2 One Way Selezione set 2 a una direzione Select Set 2 Two Way Selezione set 2 a due direzioni Select Set 2 While Held Selezione set 2 finché premuto Select Set 3 One Way Selezione set 3 a una direzione Select Set 3 Two Way Selezione set 3 a due direzioni Select Set 3 While Held Selezione set 3 finché premuto Select Set 4 One Way Selezione set 4 a una direzione Select Set 4 Two Way Selezione set 4 a due direzioni Select Set 4 While Held Selezione set 4 finché premuto Select Set 5 One Way Selezione set 5 a una direzione Select Set 5 Two Way Selezione set 5 a due direzioni Select Set 5 While Held Selezione set 5 finché premuto Select Set 6 One Way Selezione set 6 a una direzione Select Set 6 Two Way Selezione set 6 a due direzioni Select Set 6 While Held Selezione set 6 finché premuto Select Set 7 One Way Selezione set 7 a una direzione Select Set 7 Two Way Selezione set 7 a due direzioni Select Set 7 While Held Selezione set 7 finché premuto Select Set 8 One Way Selezione set 8 a una direzione Select Set 8 Two Way Selezione set 8 a due direzioni Select Set 8 While Held Selezione set 8 finché premuto [NO KEY] [NO TASTO] sec. sec. /sec. /sec. Not checked slots To delete slots, you need to select at least one Per cancellare gli slot devi selezionarne almeno uno To insert slots, you need to select at least one Per inserire gli slot devi selezionarne almeno uno Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist Il file non esiste There is no such file locally, that could be executed. Check the file on your system Set %1 Set %1 Select Set %1 Seleziona set %1 One Way a una direzione Two Way a due direzioni While Held finché premuto Choose Executable Scegli eseguibile Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Gli slot dopo un'azione Ciclo verranno eseguiti al prossimo tasto premuto. Cicli multipli possono essere aggiunti per creare partizioni in sequenza. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Ritarda il tempo dopo il quale il prossimo slot viene attivato per il tempo specificato. Gli slot attivati prima del ritardo rimarranno attivi finché il ritardo non trascorre. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. L'azione Distanza specifica che gli slot successivi verranno eseguiti solo quando un'asse si muove oltre un certo intervallo dopo la zona morta. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Inserisce un'azione Tieni. Gli slot dopo l'azione verranno eseguiti solo se il tasto viene tenuto premuto oltre all'intervallo specificato. Chose a profile to load when this slot is activated. Scegli un profilo da caricare quando questo slot viene attivato. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. L'azione Modifica mouse modificherà tutte le impostazioni della velocità mouse di una percentuale specifica mentre l'azione viene processata. Questo può tornare utile per rallentare il mouse usando un fucile da cecchino. Specify the time that keys past this slot should be held down. Specifica il tempo in cui i tasti dopo questo slot debbano restare premuti. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Inserisce un'azione di rilascio. Gli slot dopo l'azione verranno eseguiti solo dopo il rilascio di un tasto se il tasto è stato premuto dopo l'intervallo specificato. Change to selected set once slot is activated. Cambia il set selezionato quando lo slot viene attivato. Full string will be typed when a slot is activated. Una stringa verrà digitata quando uno slot viene attivato. Execute program when slot is activated. Esegue un programma quando lo slot viene attivato. Choose Profile Scegli profilo Config Files (*.amgp *.xml) File di configurazione (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Assegnazioni analogico/pad Sticks Analogici DPads DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) %1 (Joystick %2) Stick 1 Analogico 1 Enabled Attivato Assign Assegna X Axis: Asse X: Y Axis: Asse Y: Stick 2 Analogico 2 Number of Physical DPads: %1 Numero di DPad fisici: %1 Virtual DPad 1 DPad virtuale 1 Up: Su: Down: Giù: Left: Sinistra: Right: Destra: Axis %1 Asse %1 Axis %1 - Asse %1 - Axis %1 + Asse %1 + Button %1 Tasto %1 Move stick 1 along the X axis Muovere analogico 1 lungo l'asse X Move stick 1 along the Y axis Muovere analogico 1 lungo l'asse Y Move stick 2 along the X axis Muovere analogico 2 lungo l'asse X Move stick 2 along the Y axis Muovere analogico 2 lungo l'asse Y Press a button or move an axis Premere un tasto o muovere un'asse AxisEditDialog Axis Asse Mouse (Horizontal) Mouse (orizzontale) Mouse (Inverted Horizontal) Mouse (orizzontale invertito) Mouse (Vertical) Mouse (verticale) Mouse (Inverted Vertical) Mouse (verticale invertito) Arrows: Up | Down Frecce: Su | Giù Arrows: Left | Right Frecce: Sinistra | Destra Keys: W | S Tasti: W | S Keys: A | D Tasti: A | D NumPad: KP_8 | KP_2 TastNum: TN_8 | TN_2 NumPad: KP_4 | KP_6 TastNum: TN_4 | TN_6 None Niente Set the value to use as the limit for an axis. Useful for a worn out analog stick. Imposta il valore da usare come limite per un'asse. Utile per un analogico consumato. Negative Half Throttle Acceleratore negativo a metà Positive Half Throttle Acceleratore positivo a metà Haptic Trigger: Name: Nome: Specify the name of an axis. Specifica il nome di un'asse. Mouse Settings Impostazioni mouse Set the value of the dead zone for an axis. Imposta il valore della zona morta per un'asse. Presets: Preimpostazioni: Dead Zone: Zona morta: Max Zone: Zona massima: [NO KEY] [NO TASTO] Throttle setting that determines the behavior of how to interpret an axis hold or release. Impostazione dell'acceleratore che determina come interpretare il rilascio o la pressione di un'asse. Negative Throttle Acceleratore negativo Normal Normale Positive Throttle Acceleratore positivo Current Value: Valore corrente: Set Set Set %1 Set %1 Left Mouse Button Tasto sinistro del mouse Right Mouse Button Tasto destro del mouse Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog Finestra di dialogo To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Per assegnare un nuovo tasto, premere qualunque tasto della tastiera o cliccare un pulsante nella sezione Tastiera o Mouse Placeholder Segnaposto Toggle Cambio stato Enables a key press or release to only occur when a controller button is pressed. Abilita la pressione o il rilascio di un tasto solo quando il tasto di un controller viene premuto. Enables rapid key presses and releases. Turbo controller. Abilita la pressione e il rilascio rapidi di un tasto. Controller turbo. Turbo Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Last keyboard/mouse button: Slots Slot Na&me: Nome: Specify the name of a button. Specifica il nome di un tasto. Action: Azione: Specify the action that will be performed in game while this button is being used. Specifica l'azione che verrà eseguita in gioco mentre questo tasto viene usato. Advanced Avanzate Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z Z TextLabel etichetta di testo X X gain offset Y Y Start calibration Inizia calibrazione Close Chiudi Reset settings Save Salva Calibration Calibrazione Gyroscope Giroscopio Accelerometer Accelerometro Selected device doesn't have any inputs to calibrate. Il dispositivo selezionato non ha alcun input da calibrare. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Calibrazione completata. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Registrando i dati dell'accelerometro... Per favore mantieni fermo il controller. Può richiedere fino a %1 secondi. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Registrando i dati del giroscopio... Può richiedere fino a %1 secondi. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Muovi diverse volte la levetta fino al massimo in tutte le direzioni e indietro verso il centro. Può richiedere fino a %1 secondi. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Muovi diverse volte la levetta compiendo giri completi. Può richiedere fino a %1 secondi. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Proprietà finestra catturata Information About Window Informazioni sulla finestra Class: Classe: TextLabel etichetta di testo Title: Titolo: Path: Percorso: Match By Properties Trova per proprietà Class Classe Title Titolo Path Percorso Full Path Percorso completo File Name Nome file DPadContextMenu Mouse (Normal) Mouse (normale) Mouse (Inverted Horizontal) Mouse (orizzontale invertito) Mouse (Inverted Vertical) Mouse (verticale invertito) Mouse (Inverted Horizontal + Vertical) Mouse (orizzontale + verticale invertito) Arrows Frecce Keys: W | A | S | D Tasti: W | A | S | D NumPad TastNum None Niente Standard Standard Eight Way 8 direzioni 4 Way Cardinal 4 direzioni cardinali 4 Way Diagonal 4 direzioni diagonali Mouse Settings Impostazioni mouse DPadEditDialog Dialog Finestra di dialogo Presets: Preimpostazioni: Mouse (Normal) Mouse (normale) Mouse (Inverted Horizontal) Mouse (orizzontale invertito) Mouse (Inverted Vertical) Mouse (verticale invertito) Mouse (Inverted Horizontal + Vertical) Mouse (orizzontale + verticale invertito) Arrows Frecce Keys: W | A | S | D Tasti: W | A | S | D NumPad TastNum None Niente Dpad Mode: Modalità DPad: &Name: Nome: 4 Way Cardinal 4 direzioni cardinali 4 Way Diagonal 4 direzioni diagonali DPad Delay: Ritardo DPad: Time lapsed before a direction change is taken into effect. Tempo trascorso prima che il cambiamento di una direzione abbia effetto. s s Specify the name of a dpad. Specifica il nome di un DPad. Mouse Settings Impostazioni mouse Standard Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Standard: DPad a 8 regioni con due tasti direzionali attivi quando il DPad è in una regione diagonale. 8 direzioni: DPad a 8 regioni con ogni direzione che ha un tasto dedicato. Solo un tasto alla volta viene premuto. Utile per i giochi come Rogue. 4 direzioni cardinali: DPad a 4 regioni con regioni corrispondenti alla direzione cardinale del DPad. Utile per i menu. 4 direzioni diagonali: DPad a 4 regioni con ogni regione corrispondente alla zona diagonale del DPad. Eight Way 8 direzioni Set Set Set %1 Set %1 EditAllDefaultAutoProfileDialog Default Profile Profilo predefinito Profile: Profilo: Browse Sfoglia Open Config Apri configurazione Profile file path is invalid. Il percorso del profilo è invalido. ExtraProfileSettingsDialog Extra Profile Settings Altre impostazioni profilo Key Press Time: Tempo pressione tasto: 0.00 ms 0.00 ms Profile Name: Nome profilo: s s GameController Game Controller Controller di gioco GameControllerDPad DPad DPad GameControllerMappingDialog Game Controller Mapping Mappatura controller di gioco <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A A B B X X Y Y Back Back Start Start Guide Guide Left Shoulder Dorsale sinistro Right Shoulder Dorsale destro Left Stick Click Click analogico sinistro Right Stick Click Click analogico destro Left Stick X Analogico sinistro X Left Stick Y Analogico sinistro Y Right Stick X Analogico destro X Right Stick Y Analogico destro Y Left Trigger Grilletto sinistro Right Trigger Grilletto destro DPad Up DPad su DPad Left DPad sinistra DPad Down DPad giù DPad Right DPad destra Mapping Mappatura SDL 2 Game Controller Mapping String Stringa di mappatura Game controller SDL 2 Last Axis Event: Ultimo evento asse: Current Axis Detection Dead Zone: Rilevamento corrente della zona morta dell'asse: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Mappatura controller di gioco (%1) (#%2) Discard Controller Mapping? Scartare mappatura controller? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. Scartare mappatura di questo controller? Scartandola, il controller tornerà ad essere un joystick una volta aggiornati tutti i joystick. GameControllerSet Back Indietro Guide Guida Start Start LS Click Click analog SX RS Click Click analog DX L Shoulder Dorsale SX R Shoulder Dorsale DX L Trigger Grilletto SX R Trigger Grilletto DX GameControllerTrigger Trigger Grilletto JoyAccelerometerButton Up Su Down Giù Left Sinistra Right Destra Shock JoyAccelerometerSensor Accelerometer Accelerometro JoyAxis Axis Asse JoyAxisButton Negative Negativo Positive Positivo Unknown Sconosciuto Button Tasto JoyAxisContextMenu Mouse (Horizontal) Mouse (orizzontale) Mouse (Inverted Horizontal) Mouse (orizzontale invertito) Mouse (Vertical) Mouse (verticale) Mouse (Inverted Vertical) Mouse (verticale invertito) Arrows: Up | Down Frecce: Su | Giù Arrows: Left | Right Frecce: Sinistra | Destra Keys: W | S Tasti: W | S Keys: A | D Tasti: A | D NumPad: KP_8 | KP_2 TastNum: TN_8 | TN_2 NumPad: KP_4 | KP_6 TastNum: TN_4 | TN_6 None Niente Mouse Settings Impostazioni mouse Left Mouse Button Tasto sinistro del mouse Right Mouse Button Tasto destro del mouse JoyButton Processing turbo for #%1 - %2 Processando turbo per #%1 - %2 Finishing turbo for button #%1 - %2 Finendo turbo per tasto #%1 - %2 Distance change for button #%1 - %2 Cambio di distanza per tasto #%1 - %2 Button Tasto [NO KEY] [NO TASTO] [Set %1 1W] [Set %1 1DIREZ] [Set %1 2W] [Set %1 2DIREZ] [Set %1 WH] [Set %1 PREMENDO] JoyButtonContextMenu Toggle Cambio stato Turbo Turbo Clear Cancella Set Select Seleziona set Disabled Disattivato Set %1 Set %1 Set %1 1W Set %1 1DIREZ Set %1 2W Set %1 2DIREZ Set %1 WH Set %1 PREMENDO JoyButtonSlot Mouse Mouse Up Su Down Giù Left Sinistra Right Destra LB TastoMouseSX MB TastoMouseCENTRO RB TastoMouseDX Pause Pausa Hold Tieni Cycle Ciclo Distance Distanza Release Rilascia Mouse Mod Modifica mouse Press Time Tempo di pressione Delay Ritardo Load %1 Carica %1 Set Change %1 Cambio di set %1 [Text] %1 [Testo] %1 [Exec] %1 [Esec] %1 [NO KEY] [NO TASTO] JoyControlStick Stick Analogico JoyControlStickButton Up Su Down Giù Left Sinistra Right Destra Button Tasto JoyControlStickContextMenu Mouse (Normal) Mouse (normale) Mouse (Inverted Horizontal) Mouse (orizzontale invertito) Mouse (Inverted Vertical) Mouse (verticale invertito) Mouse (Inverted Horizontal + Vertical) Mouse (orizzontale + verticale invertito) Arrows Frecce Keys: W | A | S | D Tasti: W | A | S | D NumPad TastNum None Niente Standard Standard Eight Way 8 direzioni 4 Way Cardinal 4 direzioni cardinali 4 Way Diagonal 4 direzioni diagonali Mouse Settings Impostazioni mouse JoyControlStickEditDialog Dialog Finestra di dialogo X: X: 0 0 Y: Y: Distance: Distanza: Presets: Preimpostazioni: Mouse (Normal) Mouse (normale) Mouse (Inverted Horizontal) Mouse (orizzontale invertito) Mouse (Inverted Vertical) Mouse (verticale invertito) Mouse (Inverted Horizontal + Vertical) Mouse (orizzontale + verticale invertito) Arrows Frecce Keys: W | A | S | D Tasti: W | A | S | D NumPad TastNum None Niente Stick Mode: Modalità analogico: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Standard: analogico a 8 regioni con due tasti direzionali attivi quando l'analogico è in una regione diagonale. 8 direzioni: analogico a 8 regioni con ogni direzione che ha un tasto dedicato. Solo un tasto alla volta viene premuto. Utile per i giochi come Rogue. 4 direzioni cardinali: analogico a 4 regioni con regioni corrispondenti alla direzione cardinale dell'analogico. Utile per i menu. 4 direzioni diagonali: analogico a 4 regioni con ogni regione corrispondente alla zona diagonale dell'analogico. 4 Way Cardinal 4 direzioni cardinali 4 Way Diagonal 4 direzioni diagonali Modifier Zone: Dead zone value to use for an analog stick. Valore zona morta da usare per un analogico. Value when an analog stick is considered moved 100%. Valore in cui un analogico viene considerato spostato al 100%. The area (in degrees) that each diagonal region occupies. L'area (in gradi) che ogni regione diagonale occupa. Square Stick: Analogico quadrato: Percentage to modify a square stick coordinates to confine values to a circle Percentuale per modificare le coordinate di un analogico quadrato per confinare i valori ad un cerchio. % % Stick Delay: Ritardo analogico: Time lapsed before a direction change is taken into effect. Tempo trascorso prima che il cambio di una direzione entri in funzione. s s Modifier: Modificatore: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Modifica tasto che è attivo mentre l'analogico è attivo. Questo tasto è utile per assegnare zone con tasti di modificatore che possono essere usate per assegnare funzionalità cammina/corri ad un analogico. PushButton PremiTasto Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Nome: Specify the name of an analog stick. Specifica il nome di un analogico. Mouse Settings Impostazioni mouse Standard Standard Bearing: Tolleranza: % Safe Zone: % Zona sicura: Eight Way 8 direzioni Dead Zone: Zona morta: Max Zone: Zona massima: Diagonal Range: Raggio diagonale: Set Set Set %1 Set %1 JoyControlStickModifierButton Modifier Modificatore JoyDPad DPad DPad JoyDPadButton Up Su Down Giù Left Sinistra Right Destra Button Tasto JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope Giroscopio JoySensorButton Button Tasto JoySensorContextMenu Mouse Settings Impostazioni mouse JoySensorEditDialog Dialog Finestra di dialogo 0 0 Acceleration (m/s^2): Accelerazione (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Zona sicura: Presets: Preimpostazioni: Dead Zone: Zona morta: Dead zone value to use for an analog sensor. Max Zone: Zona massima: Value when an analog sensor is considered moved 100%. Diagonal Range: Raggio diagonale: The area (in degrees) that each diagonal region occupies. L'area (in gradi) che ogni regione diagonale occupa. Sensor Delay: Time lapsed before a direction change is taken into effect. s s Na&me: Nome: Specify the name of an analog sensor. Mouse Settings Impostazioni mouse Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None Niente Mouse (Normal) Mouse (normale) Mouse (Inverted Horizontal) Mouse (orizzontale invertito) Mouse (Inverted Vertical) Mouse (verticale invertito) Mouse (Inverted Horizontal + Vertical) Mouse (orizzontale + verticale invertito) Arrows Frecce Keys: W | A | S | D Tasti: W | A | S | D NumPad TastNum JoyTabWidget <New> <Nuovo> Battery level of controller Livello di batteria del controller Remove Rimuovi Remove configuration from recent list. Rimuovi configurazione dalla lista dei recenti. Load Carica Load configuration file. Carica file di configurazione. Save Salva Save changes to configuration file. Salva cambiamenti sul file di configurazione. Save As Salva come Save changes to a new configuration file. Salva cambiamenti su un nuovo file di configurazione. Sets Set Copy from Set Copia da Set Settings Impostazioni Set 1 Set 1 Set 2 Set 2 Set 3 Set 3 Set 4 Set 4 Set 5 Set 5 Set 6 Set 6 Set 7 Set 7 Set 8 Set 8 Stick/Pad Assign Assegna analogico/pad Controller Mapping Mappatura controller Quick Set Set rapido Names Nomi Toggle button name displaying. Aziona visualizzazione del nome del tasto. Pref Pref Change global profile settings. Cambia opzioni globali profilo. Reset Reset Revert changes to the configuration. Reload configuration file. Ripristina modifiche alla configurazione. Ricarica file di configurazione. Open Config Apri configurazione Config Files (*.amgp *.xml) File di configurazione (*.amgp *.xml) Config File (*.%1.amgp) File di configurazione (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Salvare cambiamenti profilo? Changes to the new profile have not been saved. Would you like to save or discard the current profile? I cambiamenti del nuovo profilo non sono stati salvati. Vuoi salvare o scartare il profilo corrente? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? I cambiamenti del profilo "%1" non sono stati salvati. Vuoi salvare o scartare il profilo corrente? Sticks Analogici Sensors Sensori DPads DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Nessun tasto è stato assegnato. Per favore usa il Set rapido per assegnare funzioni ai tasti o disattiva il nascondimento dei tasti vuoti. Set %1: %2 Set %1: %2 Set %1 Set %1 Copy Set Assignments Copia assegnazioni set Are you sure you want to copy the assignments and device properties from %1? Sei sicuro di voler copiare le assegnazioni e le proprietà dispositivo da %1? Save Config Salva configurazione Set Set Joystick Joystick Joystick JoystickStatusWindow Properties Proprietà Details Dettagli Name: Nome: %1 %1 Number: Numero: Axes: Assi: Buttons: Tasti: Hats: Hat switch: Sensors: Sensori: Battery: Batteria: Unknown Sconosciuto GUID: GUID: Game Controller: Controller di gioco: Axes Assi Buttons Tasti Hats Hat switch Sensors Sensori %1 (#%2) Properties %1 (#%2) Proprietà Empty Vuoto Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometro + Giroscopio Accelerometer Accelerometro Gyroscope Giroscopio None Niente Axis %1 Asse %1 Hat %1 Hat switch %1 No No Yes MainSettingsDialog Edit Settings Modifica impostazioni General Generale Controller Mappings Mappatura controller Language Lingua Auto Profile Auto-profilo Mouse Mouse Advanced Avanzate Pro&file Directory: <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Specifica la cartella predefinita che il programma deve usare nelle finestre di dialogo file mentre si carica un profilo o se ne salva uno nuovo.</p></body></html> Recent Profile Count: Conteggio profili recenti: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Numero di profili che possono essere messi nella lista dei profili recenti. 0 significa che il programma non impone alcun limite sui profili visualizzati.</p></body></html> Gamepad Poll Rate: Velocità di polling del gamepad: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Cambia la velocità di polling che il programma usa per scoprire nuovi eventi dai gamepad. Predefinito: 10 ms. Ridurre la velocità di polling potrebbe causare un consumo di CPU maggiore quindi per favore esamina l'impostazione che userai. Hide main window when the main window close button is clicked instead of quitting the program. Nascondi finestra principale quando il tasto chiusura della finestra principale viene cliccato invece di uscire dal programma. Close To Tray Riduci nell'area di notifica Have Windows start AntiMicroX at system startup. Avvia AntiMicroX automaticamente all'avvio di Windows. Launch At Windows Startup Esegui all'avvio di Windows Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Mostra profili recenti per tutti i controller come una lista singola nell'area di notifica. Di predefinito, usa i sottomenu. Single Profile List in Tray Lista profili singola nell'area di notifica Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Riduci a icona il programma. Per impostazione predefinita, il programma si riduce a icona se possibile. Minimize to Taskbar Riduci a icona This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Questa opzione farà nascondere tutti i tasti che non hanno slot assegnati. Bisognerà quindi usare la finestra di dialogo Set rapido per mostrare la finestra di dialogo di modifica per i tasti gamepad. Hide Empty Buttons Nascondi tasti vuoti When the program is launched, open the last known profile that was opened during the previous session. Quando il programma viene eseguito, apri l'ultimo profilo conosciuto usato nella precedente sessione. Auto Load Last Opened Profile Auto-carica l'ultimo profilo aperto Only show the system tray icon when the program first launches. Mostra solo l'icona dell'area di notifica quando il programma si apre la prima volta. Launch in Tray Esegui nell'area di notifica Associate .amgp files with AntiMicroX in Windows Explorer. Associa file .amgp con AntiMicroX in Windows Explorer. Associate Profiles Associa profili Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Show low battery notification Show empty battery notification Key Repeat Ripetizione tasto Active keys will be repeatedly pressed when this option is enabled. I tasti attivi verranno premuti a ripetizione quando questa opzione è attivata. Enable Attiva Specifies how much time should elapse before key repeating begins. Specifica quanto tempo debba passare prima che cominci la ripetizione tasto. Specifies how many times key presses will be performed per seconds. Specifica quante volte al secondo verranno premuti i tasti. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntiMicroX è stato tradotto in molte lingue da collaboratori. Di base, il programma sceglierà una traduzione adatta basandosi sulle impostazioni della lingua del tuo sistema. Tuttavia, puoi far caricare ad AntiMicroX una lingua differente a seconda di quella che scegli nella lista qui sotto.</p></body></html> Português do Brasil Portoghese (Brasile) Français Francese Deutsch Tedesco Italiano Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Niente Error Errori Warning Info Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Nota: per vedere applicate le modifiche al livello di log nell'output su terminale (non nel file di log) è richiesto il riavvio dell'applicazione Reset Reset Class Classe Title Titolo Program Programma Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disabilita l'impostazione di Windows "Aumenta precisione puntatore" mentre AntiMicroX è in esecuzione. Disattivare "Aumenta precisione puntatore" permetterà movimenti del mouse più precisi. Disable Enhance Pointer Precision Disattiva Aumenta precisione puntatore Smoothing Refresh Rate: Frequenza di aggiornamento: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. La frequenza di aggiornamento è la quantità di tempo che trascorre tra un evento mouse e l'altro. Per favore fai attenzione quando modifichi questa impostazione dato che farà consumare più CPU. Impostare un valore troppo basso può causare instabilità al sistema. Per favore esamina l'impostazione che userai. Spring Fonte Screen: Schermo: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Utilizza lo schermo specificato per la modalità fonte. Su Linux, di predefinito viene usato lo schermo primario. Su Windows, di predefinito vengono usati tutti gli schermi disponibili. Accel Numerator: Numeratore accelerazione: 0 0 Accel Denominator: Denominatore accelerazione: Accel Threshold: Soglia accelerazione: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Se i valori di accelerazione per il mouse virtuale sono stati cambiati da un altro processo, specialmente uscendo da un vecchio gioco, allora potresti voler resettare i valori di accelerazione usati dal mouse virtuale. Reset Acceleration Resetta accelerazione Delay: Ritardo: ms ms Rate: Rapporto: times/s volte/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. Qui sotto c'è una lista di mappature personalizzate salvate. Puoi utilizzare la seguente tabella per cancellare le mappature o disattivarle temporaneamente. Puoi anche disattivare le mappature incluse con SDL; basta inserire una nuova riga con il joystick GUID giusto e mettere la spunta su disattiva. Le impostazioni non avranno effetto finché non aggiorni tutti i joystick o disconnetti quel joystick in particolare. GUID GUID Mapping String Stringa di mappatura Disable? Disattivare? Delete Cancella Default Predefinito English Inglese Active Attivo Devices: Dispositivi: All Tutto Device Dispositivi Profile Profili Default? Predefinito? Add Aggiungi Edit Modifica AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Inoltre, gli utenti Windows che vogliono usare un valore basso dovrebbero anche mettere la spunta su "Disattiva Aumenta precisione puntatore" se non hanno già disattivato tale opzione in Windows. Select Default Profile Directory Seleziona la cartella del profilo predefinito Are you sure you want to delete the profile? Sei sicuro di voler cancellare il profilo? Save Log File As Salva file di log come Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu Non è stato trovato alcun joystick. Per favore collega un joystick e scegli l'opzione "Aggiorna i joystick" dal menu principale If events are not seen by a game, please click here to run this application as Administrator. Update Button &App App &Options Opzioni He&lp &Quit Esci Ctrl+Q Ctrl+Q &Update Joysticks Aggiorna i joystick Ctrl+U Ctrl+U &Hide Nascondi Ctrl+H Ctrl+H &About A proposito Ctrl+A Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page Homepage (%1) (%1) Open File Apri file Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Il livello della batteria è minore del %1 Device number: %1 Device name: %2 Numero dispositivo: %1 Nome dispositivo: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Ripristina Calibration couldn't be opened You must connect at least one controller to open the window Devi collegare almeno un controller per aprire la finestra Run as Administrator? Eseguire come amministratore? Failed to elevate program Impossibile elevare il programma Failed to restart this program as the Administrator Impossibile riavviare questo programma come Amministratore MouseAxisSettingsDialog Mouse Settings - Impostazioni mouse - Set %1 Set %1 MouseButtonSettingsDialog Mouse Settings - Impostazioni mouse - Set %1 Set %1 MouseControlStickSettingsDialog Mouse Settings Impostazioni mouse Set %1 Set %1 MouseDPadSettingsDialog Mouse Settings Impostazioni mouse Set %1 Set %1 MouseSensorSettingsDialog Mouse Settings Impostazioni mouse Set %1 Set %1 MouseSettingsDialog Mouse Settings Impostazioni mouse Mouse Mode: Modalità mouse: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. La modalità cursore viene usata per muovere il cursore del mouse sullo schermo in relazione alla sua posizione corrente a seconda di quanto muovi un'asse o se viene premuto un tasto. La modalità fonte viene usata per muovere il cursore del mouse dal centro dello schermo a seconda di quanto muovi un'asse. Il cursore del mouse tornerà al centro dello schermo quando l'asse torna nella la zona morta. Cursor Cursore Spring Fonte Acceleration: Accelerazione: Enhanced Precision Aumenta precisione Linear Lineare Quadratic Quadratico Cubic Cubico Quadratic Extreme Quadratico estremo Power Function Funzione di potenza Easing Quadratic Interpolazione quadratica Easing Cubic Interpolazione cubica Mouse Speed Settings Impostazioni velocità mouse Enable to change the horizontal and vertical speed boxes at the same time. Permette di modificare i campi di velocità orizzontale e verticale allo stesso tempo. Change Together Modifica insieme Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps 1 = 20 pixel/sec Wheel Hori. Speed: Velocità orizz. rotella: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Imposta la velocità usata per il movimento orizzontale della rotella del mouse a seconda del numero di tacche al secondo simulate. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Imposta la velocità usata per il movimento verticale della rotella del mouse a seconda del numero di tacche al secondo simulate. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Per la funzione di potenza della curva di accelerazione. Specifica il fattore da utilizzare per la sensibilità della curva. Quando il valore supera 1, il movimento del mouse verrà accelerato più velocemente nella parte bassa di un'asse. Easing Duration: Durata interpolazione: s s Highest value to accelerate mouse movement by Il valore più grande per cui accelerare il mouse x x Start %: Inizio %: Start %: Acceleration begins at this percentage of the base multiplier L'accelerazione comincia da questa percentuale del moltiplicatore di base Minimum amount of axis travel required for acceleration to begin Valore minimo di spostamento asse richiesto per far sì che cominci l'accelerazione Max Threshold: Soglia massima: Maximum axis travel before acceleration has reached the multiplier value Valore massimo di spostamento asse prima che l'accelerazione raggiunga il valore del moltiplicatore E&xtra Duration: Curve: Curva: Ease Out Sine Sinusoidale graduale Ease Out Quad Quadratico graduale Ease Out Cubic Cubico graduale Release Radius: Raggio di rilascio: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Specifica che l'area della fonte sarà relativa alla posizione del mouse impostata da una fonte non relativa. Relative Relativa Mouse Status Stato mouse X: X: 0 (0 pps) 0 (0 pixel/sec) Y: Y: 1 = 1 notch(es)/s 1 = 1 tacca(tacche)/sec Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Aumentato: curva a tre livelli che fa muovere il mouse lentamente verso la parte bassa di un'asse e velocemente nella parte alta. Lineare: il mouse si muove in modo proporzionale in un'asse. Quadratico: il mouse accelera lentamente nella parte bassa. Cubico: il mouse accelera più lentamente di Quadratico. Quadratico estremo: aumenta la velocità del mouse per 1.5 una volta che lo spostamento di un'asse raggiunge il 95%. Funzione di potenza: permette l'opzione di una curva più personalizzata. Interpolazione quadratica: la parte alta di un'asse viene gradualmente accelerata per un periodo di tempo usando una curva quadratica. Interpolazione cubica: la parte alta di un'asse viene gradualmente accelerata per un periodo di tempo usando una curva cubica. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Velocità orizz. rotella: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. Specifica il periodo di tempo (in secondi) che saranno necessari prima che il mouse sia pienamente accelerato dopo aver raggiunto la parte alta di un'asse. % % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Estende il tempo in cui l'accelerazione aggiuntiva viene applicata. Il percorso dell'asse verrà considerato. Un movimento più lento diminuirà il tempo effettivo in cui verrà applicata l'accelerazione supplementare. Spring Settings Impostazioni fonte Spring Width: Larghezza fonte: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Cambia la larghezza della regione in cui il cursore può muoversi in modalità fonte. 0 utilizzerà l'intera grandezza dello schermo. Spring Height: Altezza fonte: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. Cambia l'altezza della regione in cui il cursore può muoversi in modalità fonte. 0 utilizzerà l'intera grandezza dello schermo. %n notch(es)/s %n notch/s %n notches/s QKeyDisplayDialog Key Checker Controllo tasti <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Gestore di eventi: Native Key Value: Valore tasto nativo: 0x00000000 0x00000000 Qt Key Value: Valore tasto Qt: antimicro Key Value: QObject Super Super Menu Menu Mute Muto Vol+ Vol+ Vol- Vol- Play/Pause Riproduci/Pausa Play Riproduci Pause Pausa Prev Prec Next Succ Mail E-mail Home Principale Media Media Search Cerca Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program Chiudendo il programma # of joysticks found: %1 № di joystick trovati: %1 List Joysticks: Lista joystick: --------------- --------------- Joystick %1: Joystick %1: Attempting to use fallback option %1 for event generation. Tentativo di utilizzo dell'opzione alternativa %1 per la generazione eventi. Failed to open event generator. Exiting. Impossibile aprire il generatore di eventi. Esco. Using %1 as the event generator. Sto usando %1 come generatore eventi. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Unknown log level: Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Il profilo in %1 non è un file XML. Profile location %1 does not exist. Il profilo in %1 non esiste. Controller identifier is not a valid value. L'identificatore controller non è un valore valido. An invalid set number '%1' was specified. È stato specificato un numero di set '%1' invalido. Controller identifier '%s'' is not a valid value. L'identificatore controller '%s'' non è un valore valido. No set number was specified. Non è stato specificato un numero di set. An invalid event generator was specified. È stato specificato un generatore di eventi invalido. No event generator string was specified. Nessuna stringa di generatore eventi è stata specificata. No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. La versione xinput dev'essere almeno 2.0. Non avverrà alcuna modifica all'accelerazione mouse. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set Set rapido <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>Per favore premi un tasto o muovi un'asse su %1 (<span style=" font-weight:600;">%2</span>).<br/>Verrà mostrata una finestra di dialogo che<br/>ti permetterà di creare un'assegnazione.</p></body></html> Quick Set %1 Set rapido %1 SetAxisThrottleDialog Throttle Change Modifica acceleratore The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? L'impostazione dell'acceleratore per l'asse %1 è cambiata. Vuoi distribuire questa modifica su tutti i set? SetJoystick Set %1: %2 Set %1: %2 Set %1 Set %1 SetNamesDialog Set Name Settings Impostazioni nome set Set 1 Set 1 Set 2 Set 2 Set 3 Set 3 Set 4 Set 4 Set 5 Set 5 Set 6 Set 6 Set 7 Set 7 Set 8 Set 8 Name Nome SimpleKeyGrabberButton Mouse Mouse SpringModeRegionPreview Spring Mode Preview Anteprima modalità fonte UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Impossibile trovare un valido file di dispositivo uinput. Per favore controlla di aver caricato il modulo uinput. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Impossibile aprire il file di dispositivo uinput. Per favore controlla di avere i permessi di scrittura sul dispositivo. Using uinput device file %1 File di dispositivo uinput %1 in uso UInputHelper a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z Esc Esc F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace BackSpace Tab Tab [ [ ] ] \ \ CapsLock BlocMaiusc ; ; ' ' Enter Invio Shift_L Maiusc_SX , , . . / / Ctrl_L Ctrl_SX Super_L Super_SX Alt_L Alt_SX Space Spazio Alt_R Alt_DX Menu Menu Ctrl_R Ctrl_DX Shift_R Maiusc_DX Up Su Left Sinistra Down Giù Right Destra PrtSc Stamp Ins Ins Del Canc Home Home End Fine PgUp PgSu PgDn PgGiù NumLock BlocNum * * + + KP_Enter TN_Invio KP_1 TN_1 KP_2 TN_2 KP_3 TN_3 KP_4 TN_4 KP_5 TN_5 KP_6 TN_6 KP_7 TN_7 KP_8 TN_8 KP_9 TN_9 KP_0 TN_0 SCLK BlocScorr Pause Pausa Super_R Super_DX Mute Muto VolDn VolGiù VolUp VolSu Play Riproduci Stop Ferma Prev Prec Next Succ [NO KEY] [NO TASTO] UnixWindowInfoDialog Captured Window Properties Finestra proprietà catturate Information About Window Informazioni sulla finestra Class: Classe: TextLabel etichetta di testo Title: Titolo: Path: Percorso: Match By Properties Trova per proprietà Class Classe Title Titolo Path Percorso VDPad VDPad VDPad VirtualKeyPushButton Space Spazio Tab Tab Shift (L) Maiusc (SX) Shift (R) Maiusc (DX) Ctrl (L) Ctrl (SX) Ctrl (R) Ctrl (DX) Alt (L) Alt (SX) Alt (R) Alt (DX) Alt Gr ` ` ~ ~ - - = = [ [ ] ] \ \ Caps Caps ; ; ' ' , , . . / / ESC ESC PRTSC STAMP SCLK BLOCSCORR INS INS PGUP PGSU DEL CANC PGDN PGGIU 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK BLOC NUM * * + + Enter Invio Del Canc < < : : Super (L) Super (SX) Menu Menu Up Su Down Giù Left Sinistra Right Destra VirtualKeyboardMouseWidget Keyboard Tastiera Mouse Mouse Mouse Settings Impostazioni mouse Left Mouse Sinistra Up Mouse Su Left Button Mouse Tasto sinistro Middle Button Mouse Tasto centrale Right Button Mouse Tasto destro Wheel Up Mouse Rotella su Wheel Left Mouse Rotella sinistra Wheel Right Mouse Rotella destra Wheel Down Mouse Rotella giù Down Mouse Giù Right Mouse Destra Button 4 Mouse Tasto 4 Mouse 8 Mouse Mouse 8 Button 5 Mouse Tasto 5 Mouse 9 Mouse Mouse 9 NONE NIENTE [NO KEY] [NO TASTO] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Applicazioni Browser Back Browser indietro Browser Favorites Browser preferiti Browser Forward Browser avanti Browser Home Browser home Browser Refresh Browser aggiorna Browser Search Browser cerca Browser Stop Browser stop Calc Calc Email E-mail F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media Media Media Next Media successivo Media Play Media play Media Previous Media precedente Media Stop Media stop Search Cerca Volume Down Volume giù Volume Mute Volume muto Volume Up Volume su VirtualMousePushButton INVALID INVALIDO WinAppProfileTimerDialog Capture Application Cattura applicazione After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Dopo aver premuto il tasto "Cattura applicazione", per favore seleziona la finestra dell'applicazione con cui vuoi associare un profilo. L'applicazione attiva verrà catturata dopo il numero di secondi scelto. Timer: Timer: Seconds Secondi Cancel Annulla WinExtras [NO KEY] [NO TASTO] AntiMicro Profile X11Extras ESC ESC Tab Tab Space Spazio DEL CANC Return Invio KP_Enter TN_Invio Backspace Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. Estensione xinput non trovata. Non avverrà alcuna modifica all'accelerazione mouse. xinput version must be at least 2.0. No mouse acceleration changes will occur. La versione xinput dev'essere almeno 2.0. Non avverrà alcuna modifica all'accelerazione mouse. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 PtrFeedbackClass non è stato trovato per il puntatore virtuale. Non avverrà alcuna modifica all'accelerazione del mouse con id=%1 Changing mouse acceleration for device with id=%1 Modificando l'accelerazione mouse per il dispositivo con id=%1 XMLConfigReader Could not write updated profile XML to file %1. Impossibile scrivere profilo XML aggiornato sul file %1. XMLConfigWriter Could not write to profile at %1. Impossibile scrivere su profilo a %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Esegui programma solo nella barra di sistema. Launch program with the tray menu disabled Avvia il programma con l'icona nel vassoio di sistema disabilitata Launch program without the main window displayed Avvia il programma senza mostrare la finestra principale Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_ja.ts000066400000000000000000012773031471077622000273660ustar00rootroot00000000000000 AboutDialog About Version バージョン Info 情報 Changelog Credits AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 License ライセンス Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 AddEditAutoProfileDialog Auto Profile Dialog Pro&file: Browse Window: ウィンドウ: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Detect Window Properties &Class: T&itle: set partial title Application: アプリケーション: Select De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Set as Default for Controller A different profile is already selected as the default for this device. Current (%1) Open Config Select Program Programs (*.exe) Please use the main default profile selection. Main Profile Already selected Chosen Profile The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. Capture Application Window Could not obtain information for the selected window. Application Capture Failed Profile file path is invalid. No window matching property was specified. Program path is invalid or not executable. File is not an .exe file. No window matching property was selected. AdvanceButtonDialog Advanced 詳細設定 Assignments 割り当て Toggle トグル Turbo 連射 Set Selector Blank or KB/M Hold Pause Pause Cycle Distance Insert Delete 削除 Clear All Time: 0.01s 0.01 秒 0s 0 秒 Insert a pause that occurs in between key presses. Release Insert a new blank slot. Delete a slot. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. 0m 0 分 &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: % % Mouse Mod Press Time Delay Execute Load 読み込み Set Change Text Entry Join Split Placeholder 0 0 Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After seconds Executable: ... Arguments: Enabled 有効 Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Delay: 0.10s 0.10 秒 Rate: 10.0/s Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] [割り当てなし] sec. /sec. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 セット %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) 構成ファイル (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks スティック DPads 十字キー Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) %1 (ジョイスティック %2) Stick 1 スティック 1 Enabled 有効 Assign 割り当て X Axis: X 軸: Y Axis: Y 軸: Stick 2 スティック 2 Number of Physical DPads: %1 物理方向キーの数: %1 Virtual DPad 1 仮想方向キー 1 Up: 上: Down: 下: Left: 左: Right: 右: Axis %1 軸 %1 Axis %1 - 軸 %1 - Axis %1 + 軸 %1 + Button %1 ボタン %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Haptic Trigger: Name: 名前: Specify the name of an axis. Mouse Settings マウスの設定 Set the value of the dead zone for an axis. Presets: プリセット: Dead Zone: Max Zone: [NO KEY] [割り当てなし] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set セット Set %1 セット %1 Left Mouse Button 左マウスボタン Right Mouse Button 右マウスボタン Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab 割り当てを新規作成するには、キーボードのキーを押すか、「キーボード」あるいは「マウス」タブのいずれかのボタンをクリックしてください Placeholder Toggle トグル Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo 連射 Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Last keyboard/mouse button: Slots Na&me: 名前(&M): Specify the name of a button. Action: アクション: Specify the action that will be performed in game while this button is being used. Advanced 詳細設定 Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel X X gain offset Y Y Start calibration Close Reset settings Save 保存 Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: タイトル: Path: Match By Properties Class Title タイトル Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings マウスの設定 DPadEditDialog Dialog Presets: プリセット: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings マウスの設定 Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set セット Set %1 セット %1 EditAllDefaultAutoProfileDialog Default Profile Profile: プロファイル: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: プロファイル名: s s GameController Game Controller ゲームコントローラー GameControllerDPad DPad 十字キー GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A A B B X X Y Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X 左スティック X Left Stick Y 左スティック Y Right Stick X 右スティック X Right Stick Y 右スティック Y Left Trigger 左トリガー Right Trigger 右トリガー DPad Up 十字キー↑ DPad Left 十字キー← DPad Down 十字キー↓ DPad Right 十字キー→ Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger 左トリガー R Trigger 右トリガー GameControllerTrigger Trigger トリガー JoyAccelerometerButton Up Down Left Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Negative Positive Unknown 不明 Button ボタン JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings マウスの設定 Left Mouse Button 左マウスボタン Right Mouse Button 右マウスボタン JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button ボタン [NO KEY] [割り当てなし] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle トグル Turbo 連射 Clear Set Select Disabled Set %1 セット %1 Set %1 1W セット %1 1W Set %1 2W セット %1 2W Set %1 WH JoyButtonSlot Mouse マウス Up Down Left Right LB MB RB Pause Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] [割り当てなし] JoyControlStick Stick スティック JoyControlStickButton Up Down Left Right Button ボタン JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings マウスの設定 JoyControlStickEditDialog Dialog X: X: 0 0 Y: Y: Distance: Presets: プリセット: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: 名前: Specify the name of an analog stick. Mouse Settings マウスの設定 Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set セット Set %1 セット %1 JoyControlStickModifierButton Modifier JoyDPad DPad 十字キー JoyDPadButton Up Down Left Right Button ボタン JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button ボタン JoySensorContextMenu Mouse Settings マウスの設定 JoySensorEditDialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: Presets: プリセット: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. s Na&me: Specify the name of an analog sensor. Mouse Settings マウスの設定 Roll (°/s) Pitch (°/s) Yaw (°/s) Set セット Set %1 セット %1 JoySensorPreset None Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad JoyTabWidget <New> <新規> Battery level of controller Remove 削除 Remove configuration from recent list. Load 読み込み Load configuration file. Save 保存 Save changes to configuration file. Save As 別名保存 Save changes to a new configuration file. Sets セット Copy from Set セットからコピー Settings 設定 Set 1 セット 1 Set 2 セット 2 Set 3 セット 3 Set 4 セット 4 Set 5 セット 5 Set 6 セット 6 Set 7 セット 7 Set 8 セット 8 Stick/Pad Assign Controller Mapping Quick Set クイックセット Names Toggle button name displaying. Pref Change global profile settings. Reset リセット Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) 構成ファイル (*.amgp *.xml) Config File (*.%1.amgp) 構成ファイル (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks スティック Sensors DPads 十字キー No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 セット %1: %2 Set %1 セット %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set セット Joystick Joystick ジョイスティック JoystickStatusWindow Properties プロパティ Details Name: 名前: %1 %1 Number: Axes: 軸: Buttons: ボタン: Hats: Sensors: Battery: Unknown 不明 GUID: GUID: Game Controller: ゲームコントローラー: Axes Buttons ボタン Hats Sensors %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None Axis %1 軸 %1 Hat %1 No いいえ Yes はい MainSettingsDialog Edit Settings General 全般 Controller Mappings Language 言語 Auto Profile Mouse マウス Advanced 詳細設定 <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Windows の起動と同時に開始 Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar タスクバーに入れる This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles プロファイルを関連付け Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Show low battery notification Show empty battery notification Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable 有効 Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info 情報 Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset リセット Class Title タイトル Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: スクリーン: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: Pro&file Directory: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID GUID Mapping String Disable? Delete 削除 Default デフォルト English 英語 Active Devices: デバイス: All Device デバイス Profile プロファイル Default? Add 追加 Edit 編集 AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu ジョイスティックが見つかりません。 ジョイスティックを接続し、メインメニューの「ジョイスティックを更新」を選択してください If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Options オプション(&O) He&lp &Quit 終了(&Q) Ctrl+Q Ctrl+Q &Update Joysticks ジョイスティックを更新(&U) Ctrl+U Ctrl+U &Hide 隠す(&H) Ctrl+H Ctrl+H &About AntiMicroX について(&A) Ctrl+A Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page ホームページ (%1) (%1) Open File Run as Administrator? Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. Failed to elevate program Failed to restart this program as the Administrator %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window MouseAxisSettingsDialog Mouse Settings - Set %1 セット %1 MouseButtonSettingsDialog Mouse Settings - Set %1 セット %1 MouseControlStickSettingsDialog Mouse Settings マウスの設定 Set %1 セット %1 MouseDPadSettingsDialog Mouse Settings マウスの設定 Set %1 セット %1 MouseSensorSettingsDialog Mouse Settings マウスの設定 Set %1 セット %1 MouseSettingsDialog Mouse Settings マウスの設定 Mouse Mode: マウスモード: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor カーソル Spring Acceleration: 加速: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: X: 0 (0 pps) Y: Y: 1 = 1 notch(es)/s 1 = 1 ノッチ/秒 Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s %n ノッチ/秒 QKeyDisplayDialog Key Checker キーチェッカー <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: イベントハンドラ: Native Key Value: ネイティブキー値: 0x00000000 0x00000000 Qt Key Value: Qt キー値: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Pause Prev Next Mail Home Home Media メディア Search 検索 Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: ジョイスティック %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set クイックセット <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 クイックセット %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 セット %1: %2 Set %1 セット %1 SetNamesDialog Set Name Settings Set 1 セット 1 Set 2 セット 2 Set 3 セット 3 Set 4 セット 4 Set 5 セット 5 Set 6 セット 6 Set 7 セット 7 Set 8 セット 8 Name SimpleKeyGrabberButton Mouse マウス SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z Esc Esc F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace BackSpace Tab Tab [ [ ] ] \ \ CapsLock CapsLock ; ; ' ' Enter Enter Shift_L , , . . / / Ctrl_L Super_L Alt_L Space スペース Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc PrtSc Ins Del Del Home Home End End PgUp PgUp PgDn PgDn NumLock NumLock * * + + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] [割り当てなし] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: タイトル: Path: Match By Properties Class Title タイトル Path VDPad VDPad VirtualKeyPushButton Space スペース Tab Tab Shift (L) Shift (左) Shift (R) Shift (右) Ctrl (L) Ctrl (左) Ctrl (R) Ctrl (右) Alt (L) Alt (左) Alt (R) Alt (右) Alt Gr ` ` ~ ~ - - = = [ [ ] ] \ \ Caps Caps ; ; ' ' , , . . / / ESC PRTSC SCLK INS PGUP DEL PGDN 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK * * + + Enter Enter Del Del < < : : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard キーボード Mouse マウス Mouse Settings マウスの設定 Left Mouse Up Mouse Left Button Mouse 左ボタン Middle Button Mouse 中ボタン Right Button Mouse 右ボタン Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse ボタン 4 Mouse 8 Mouse マウス 8 Button 5 Mouse ボタン 5 Mouse 9 Mouse マウス 9 NONE 割り当てなし [NO KEY] [割り当てなし] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications アプリケーション Browser Back ブラウザ: 戻る Browser Favorites ブラウザ: お気に入り Browser Forward ブラウザ: 進む Browser Home ブラウザ: ホーム Browser Refresh ブラウザ: 更新 Browser Search ブラウザ: 検索 Browser Stop Calc Email Eメール F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media メディア Media Next メディア: 次へ Media Play メディア: 再生 Media Previous メディア: 前へ Media Stop メディア: 停止 Search 検索 Volume Down 音量: 下げる Volume Mute 音量: ミュート Volume Up 音量: 上げる VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: タイマー: Seconds Cancel キャンセル WinExtras [NO KEY] [割り当てなし] AntiMicro Profile X11Extras ESC Tab Tab Space スペース DEL Return KP_Enter Backspace Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_ko.ts000066400000000000000000015704431471077622000274060ustar00rootroot00000000000000 AboutDialog About 정보 Version 버전 Info 정보 Changelog 변경 내역 Credits 크레딧 AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">원래 Travis Nickles가 개발 &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">다음은 https://github.com/AntiMicro 의 AntiMicro 그룹에서 유지 관리합니다.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">그런 다음 https://github.com/juliagoda 에서 juliagoda가 작성합니다.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">이제 https://github.com/AntiMicroX/antimicrox 에서 유지 관리됩니다.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">기여자:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">번역가:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">DDinghoya &lt;ddinghoya@gmail.com&gt; - 한국어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - 브라질 포르투갈어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - 중국어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - 프랑스어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - 독일어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - 독일어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - 일본어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - 러시아어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - 세르비아어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - 우크라이나어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - 스페인어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - &lt;wazaaaaa00@gmail.com&gt; - 이탈리아어</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - 폴란드어</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU 일반 공개 라이센스</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">버전 3, 2007년 6월 29일</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 자유 소프트웨어 재단, 주식회사. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">모든 사람이 이 라이센스 문서의 그대로 복사 및 배포할 수 있지만 변경하는 것은 허용되지 않습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">전문</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU 일반 공개 라이센스는 소프트웨어 및 기타 작업에 대한 무료 카피레프트 라이센스입니다. 대부분의 소프트웨어 및 기타 실제 작업에 대한 라이센스는 작업을 공유하고 변경할 자유를 박탈하도록 설계되었습니다. 대조적으로, GNU 일반 공개 라이센스는 프로그램의 모든 버전을 공유하고 변경할 수 있는 자유를 보장하여 모든 사용자에게 무료 소프트웨어로 남도록 하기 위한 것입니다. 자유 소프트웨어 재단은 대부분의 소프트웨어에 GNU 일반 공개 라이센스를 사용합니다. 이는 작성자가 이러한 방식으로 발표한 다른 모든 작업에도 적용됩니다. 프로그램에도 적용할 수 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">우리가 자유 소프트웨어에 대해 말할 때 우리는 가격이 아니라 자유를 언급합니다. 우리의 일반 공개 라이센스는 귀하가 자유 소프트웨어의 복사본을 배포할 수 있는 자유 (원하는 경우 비용을 청구할 수 있음)를 보장하고, 소스 코드를 받거나 원하는 경우 얻을 수 있고, 소프트웨어를 변경할 수 있도록 설계되었습니다. 또는 새로운 무료 프로그램에서 일부를 사용하고 이러한 작업을 수행할 수 있다는 것을 알고 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">귀하의 권리를 보호하기 위해 다른 사람들이 귀하에게 이러한 권리를 거부하거나 권리 포기를 요청하는 것을 방지해야 합니다. 따라서 소프트웨어 사본을 배포하거나 수정하는 경우 다른 사람의 자유를 존중할 책임이 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">예를 들어, 그러한 프로그램의 사본을 무료로 또는 유료로 배포하는 경우 귀하가 받은 것과 동일한 자유를 수신자에게 양도해야 합니다. 그들도 소스 코드를 받거나 받을 수 있는지 확인해야 합니다. 그리고 그들이 자신의 권리를 알 수 있도록 이 약관을 보여주어야 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GPL을 사용하는 개발자는 다음 두 단계를 통해 귀하의 권리를 보호합니다:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) 소프트웨어에 대한 저작권을 주장, (2) 소프트웨어를 복사, 배포 및/또는 수정할 수 있는 법적 권한을 부여하는 이 라이센스를 제공합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">개발자와 저작자의 보호를 위해 GPL은 이 무료 소프트웨어에 대한 보증이 없음을 명확하게 설명합니다. 사용자와 작성자 모두를 위해 GPL은 수정된 버전이 변경된 것으로 표시되어 문제가 이전 버전의 작성자에게 잘못 귀속되지 않도록 해야 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">일부 장치는 제조업체가 그렇게 할 수 있지만 사용자가 내부에 수정된 버전의 소프트웨어를 설치하거나 실행할 수 있는 액세스를 거부하도록 설계되었습니다. 이는 사용자의 소프트웨어 변경 자유를 보호하려는 목적과 근본적으로 양립할 수 없습니다. 이러한 남용의 체계적인 패턴은 개인이 사용하는 제품 영역에서 발생하며 정확히는 가장 용납할 수 없는 부분입니다. 따라서 우리는 이러한 제품에 대한 관행을 금지하기 위해 이 버전의 GPL을 설계했습니다. 그러한 문제가 다른 도메인에서 상당히 발생하는 경우, 우리는 사용자의 자유를 보호하기 위해 필요에 따라 이 조항을 GPL의 향후 버전에서 해당 도메인으로 확장할 준비가 되어 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">마지막으로 모든 프로그램은 소프트웨어 특허에 의해 끊임없이 위협받고 있습니다. 국가는 특허가 범용 컴퓨터에서 소프트웨어의 개발 및 사용을 제한하는 것을 허용해서는 안 되지만 허용하는 경우 자유 프로그램에 적용된 특허가 해당 프로그램을 독점적으로 만들 수 있다는 특별한 위험을 피하고자 합니다. 이를 방지하기 위해 GPL은 특허를 사용하여 프로그램을 무료 아님으로 만들 수 없도록 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">복사, 배포 및 수정에 대한 정확한 약관은 다음과 같습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">이용약관</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. 정의.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;저작권&quot;은 또한 반도체 마스크와 같은 다른 종류의 저작물에 적용되는 저작권과 유사한 법률을 의미합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">본 &quot;프로그램&quot;은 본 라이센스에 따라 라이센스가 부여된 모든 저작물을 의미합니다. 각 라이센스 사용자는 &quot;귀하&quot;로 지정됩니다. &quot;라이센스 사용자&quot; 및 &quot;수신자&quot;는 개인 또는 조직일 수 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;수정&quot;하려면 저작물은 정확한 사본을 만드는 것 외에 저작권 허가가 필요한 방식으로 저작물의 전체 또는 일부를 복사하거나 각색하는 것을 의미합니다. 그 결과물인 저작물을 이전 작업의 &quot;수정된 버전"&quot; 또는 이전 작업을 &quot;기반&quot;으로 한 작업이라고 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;적용되는 작업&quot;은 수정되지 않은 프로그램 또는 프로그램을 기반으로 하는 작업을 의미합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;전파&quot; 저작물이란 컴퓨터에서 실행하거나 개인 사본을 수정하는 경우를 제외하고 허가 없이 해당 저작권법에 따른 침해에 대해 직접 또는 이차적으로 책임을 지게 하는 모든 작업을 의미합니다. 전파에는 복사, 배포(수정 여부에 관계없이), 대중에게 제공, 일부 국가에서는 기타 활동도 포함됩니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;전달&quot; 저작물은 다른 당사자가 복제물을 만들거나 받을 수 있도록 하는 모든 종류의 전파를 의미합니다. 사본을 전송하지 않고 컴퓨터 네트워크를 통한 사용자와의 단순한 상호 작용은 전달되지 않습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">대화형 사용자 인터페이스에 &quot;적절한 법적 고지&quot;가 표시됩니다. (1) 적절한 저작권 표시를 표시하고 (2) 사용자에게 저작물에 대한 보증이 없음을 알리는 편리하고 눈에 띄게 보이는 기능을 포함하는 범위 내에서 (보증이 제공되는 경우 제외) 이 라이센스에 따른 작업과 이 라이센스의 사본을 보는 방법을 전달할 수 있습니다. 인터페이스가 메뉴와 같은 사용자 명령 또는 옵션 목록을 제공하는 경우 목록의 눈에 띄는 항목이 이 기준을 충족합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. 소스 코드.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">저작물의 &quot;소스 코드&quot;는 저작물의 수정을 위해 선호되는 저작물의 형태를 의미합니다. &quot;객체 코드&quot;는 저작물의 소스가 아닌 모든 형태를 의미합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;표준 인터페이스&quot;는 공인된 표준 기관에서 정의한 공식 표준이거나 특정 프로그래밍 언어에 대해 지정된 인터페이스의 경우 해당 언어로 작업하는 개발자 사이에서 널리 사용되는 인터페이스를 의미합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">실행 가능한 저작물의 &quot;시스템 라이브러리&quot;에는 (a) 주요 구성 요소를 패키징하는 일반적인 형식에 포함되지만 해당 주요 구성 요소의 일부가 아닌 전체 저작물 이외의 모든 것이 포함됩니다. 해당 주요 구성 요소와 함께 작업을 사용할 수 있도록 하거나 구현이 소스 코드 형식으로 대중에게 제공되는 표준 인터페이스를 구현합니다. 이 맥락에서 &quot;주요 구성 요소&quot;는 실행 가능한 작업이 실행되는 특정 운영 체제(있는 경우)의 주요 필수 구성 요소(커널, 창 시스템 등) 또는 작업을 생성하는 데 사용되는 컴파일러, 또는 그것을 실행하는 데 사용되는 개체 코드 인터프리터를 의미합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">개체 코드 형식의 저작물에 대한 &quot;해당 소스&quot;는 개체 코드를 생성, 설치 및 실행하고 (실행 가능한 작업의 경우) 작업을 수정하는 데 필요한 모든 소스 코드를 의미하며 이러한 활동을 제어하는 스크립트를 포함합니다. 그러나 저작물의 시스템 라이브러리나 범용 도구 또는 일반적으로 사용 가능한 무료 프로그램은 포함되지 않으며 이러한 활동을 수행하는 데 수정되지 않고 사용되지만 저작물의 일부는 아닙니다. 예를 들어, 해당 소스에는 저작물의 소스 파일과 관련된 인터페이스 정의 파일, 공유 라이브러리의 소스 코드 및 해당 하위 프로그램과 하위 프로그램 간의 긴밀한 데이터 통신 또는 제어 흐름과 같이 저작물이 특별히 요구하도록 설계된 동적으로 연결된 하위 프로그램 및 작업의 다른 부분을 포함됩니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">해당 소스는 사용자가 해당 소스의 다른 부분에서 자동으로 재생성할 수 있는 어떤 것도 포함할 필요가 없습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">소스 코드 형식의 작업에 대한 해당 소스는 동일한 작업입니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. 기본 권한.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">본 라이센스에 따라 부여된 모든 권리는 프로그램의 저작권 기간 동안 부여되며 명시된 조건이 충족되는 경우 취소할 수 없습니다. 본 라이센스는 수정되지 않은 프로그램을 실행할 수 있는 귀하의 무제한 권한을 명시적으로 확인합니다. 적용 대상 작업 실행의 결과물은 해당 콘텐츠가 주어진 출력이 적용 대상 작업을 구성하는 경우에만 이 라이센스의 적용을 받습니다. 이 라이센스는 저작권법에서 제공하는 공정 사용 또는 이에 상응하는 기타 권리를 인정합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">귀하는 귀하의 라이센스가 유효한 한 조건 없이 귀하가 전달하지 않는 해당 저작물을 제작, 실행 및 전파할 수 있습니다. 귀하는 귀하가 통제하지 않는 모든 자료를 전달할 때 본 라이센스의 조건을 준수한다는 조건 하에 해당 저작물을 독점적으로 수정하게 하거나 해당 작업을 실행할 수 있는 시설을 제공할 목적으로만 다른 사람에게 해당 저작물을 전달할 수 있습니다. 저작권. 따라서 귀하를 위해 적용되는 저작물을 만들거나 실행하는 사람들은 귀하와의 관계 외부에서 귀하의 저작권이 있는 자료의 복사본을 만드는 것을 금지하는 조건에 따라 귀하의 지시와 통제 하에 귀하를 대신하여 독점적으로 작업을 수행해야 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">기타 상황에서의 운송은 아래 명시된 조건에서만 허용됩니다. 2차 라이센스는 허용되지 않습니다. 섹션 10은 이를 불필요하게 만듭니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. 우회방지법으로부터 사용자의 법적 권리 보호.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">적용되는 작업은 1996년 12월 20일에 채택된 WIPO 저작권 조약 제11조에 따른 의무를 이행하는 관련 법률 또는 그러한 조치의 우회를 금지하거나 제한하는 유사한 법률에 따라 효과적인 기술적 조치의 일부로 간주되지 않습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">적용 대상 저작물을 전달할 때, 귀하는 해당 저작물에 대해 본 라이센스에 따른 권리를 행사함으로써 그러한 우회가 영향을 미치는 범위 내에서 기술적 조치의 우회를 금지하는 법적 권한을 포기하며, 해당 저작물의 작동 또는 수정을 제한하려는 의도를 부인합니다 저작물의 사용자에 대해 기술적 조치의 우회를 금지하는 귀하 또는 제3자의 법적 권리를 시행하는 수단으로 작동합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. 상세한 사본 전달.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">귀하는 각 사본에 적절한 저작권 표시를 눈에 띄게 적절하게 게시하는 경우 어떤 매체로든 수신하는 대로 프로그램 소스 코드의 축약된 사본을 전달할 수 있습니다. 본 라이센스 및 섹션 7에 따라 추가된 비허용 조건이 코드에 적용된다는 내용의 모든 고지를 그대로 유지합니다. 보증 부재에 대한 모든 통지를 그대로 유지하십시오. 모든 수신자에게 프로그램과 함께 이 라이센스의 사본을 제공하십시오.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">귀하는 귀하가 전달하는 각 사본에 대해 어떠한 가격이나 무료로 청구할 수 있으며, 유료로 지원 또는 보증 보호를 제공할 수 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. 수정된 소스 버전 전달.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">귀하는 다음 조건을 모두 충족하는 경우 프로그램에 기반한 저작물 또는 프로그램에서 이를 생성하기 위한 수정 사항을 제4조의 조건에 따라 소스 코드의 형태로 전달할 수 있습니다:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) 저작물에는 수정했다는 내용과 관련 날짜를 명시하는 눈에 띄는 고지가 있어야 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) 저작물은 본 라이센스 및 섹션 7에 따라 추가된 모든 조건에 따라 배포되었음을 알리는 눈에 띄는 고지를 포함해야 합니다. 이 요구 사항은 &quot;모든 고지를 온전하게 유지&quot;하기 위해 섹션 4의 요구 사항을 수정합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) 귀하는 사본을 소유하게 된 모든 사람에게 본 라이센스에 따라 전체 작업에 대한 라이센스를 부여해야 합니다. 따라서 이 라이센스는 적용 가능한 섹션 7 추가 조건과 함께 패키지 방식에 관계없이 전체 작업 및 모든 부분에 적용됩니다. 본 라이센스는 다른 방식으로 저작물에 라이센스를 부여할 수 있는 권한을 부여하지 않지만, 귀하가 별도로 받은 경우 그러한 권한이 무효화되지는 않습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) 저작물에 대화형 사용자 인터페이스가 있는 경우 각 인터페이스에는 적절한 법적 고지가 표시되어야 합니다. 그러나 프로그램에 적절한 법적 고지를 표시하지 않는 대화형 인터페이스가 있는 경우 작업에서 그렇게 할 필요는 없습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">해당 저작물의 성격상 해당 저작물의 확장이 아니며 더 큰 프로그램을 형성하기 위해 저장 또는 배포판의 볼륨 내에서 또는 그 위에 결합되지 않은 다른 개별적이고 독립적인 저작물과 함께 적용되는 저작물의 편집 편집물과 그 결과 저작권이 편집물 사용자의 접속 또는 법적 권리를 개별 저작물이 허용하는 범위 이상으로 제한하는 데 사용되지 않는 경우 매체를 &quot;집합체&quot;라고 합니다. 적용 대상 작업을 집합체에 포함한다고 해서 집합체의 다른 부분에 본 라이센스가 적용되는 것은 아닙니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. 출처가 아닌 양식 전달.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">귀하는 본 라이센스의 조건에 따라 기계 판독 가능한 해당 소스를 다음 방법 중 하나로 전달하는 경우 4항 및 5항의 조건에 따라 대상 코드 형식으로 해당 작업을 전달할 수 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) 소프트웨어 교환에 일반적으로 사용되는 내구성 있는 물리적 매체에 고정된 해당 소스와 함께 물리적 제품 (물리적 배포 매체 포함)에 포함되거나 구현된 개체 코드를 전달합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) 최소 3년 동안 유효하고 해당 제품 모델에 대한 예비 부품 또는 고객 지원을 제공하는 한 유효한 서면 제안과 함께 물리적 제품 (물리적 유통 매체 포함)에 포함되거나 구현된 객체 코드를 전달하고, 객체 코드를 소유한 사람에게 다음 중 하나를 제공 (1) 이 라이센스가 적용되는 제품의 모든 소프트웨어에 대한 해당 소스의 사본을 소프트웨어 교환에 일반적으로 사용되는 내구성 있는 물리적 매체에 이러한 소스 전달을 물리적으로 수행하는 데 드는 합리적인 비용 이하의 가격으로 제공 또는 (2) 네트워크 서버에서 해당 소스를 무료로 복사할 수 있는 접속 권한입니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) 해당 소스를 제공하기 위해 서면 제안 사본과 함께 개체 코드의 개별 사본을 전달합니다. 이 대안은 6b항에 따라 이러한 제안과 함께 개체 코드를 받은 경우에만 가끔 비상업적으로만 허용됩니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) 지정된 장소 (무료 또는 유료)에서 접속을 제공하여 객체 코드를 전달하고 동일한 방법으로 해당 소스에 대한 동등한 접속을 추가 비용 없이 동일한 장소를 통해 제공합니다. 수신자가 객체 코드와 함께 해당 소스를 복사하도록 요구할 필요는 없습니다. 목적 코드를 복사할 장소가 네트워크 서버인 경우 해당 소스는 동일한 복사 기능을 지원하는 다른 서버(귀하 또는 제3자에 의해 운영됨)에 있을 수 있는 해당 소스를 찾습니다. 해당 소스를 호스팅하는 서버에 관계없이 이러한 요구 사항을 충족하는 데 필요한 기간 동안 해당 소스를 사용할 수 있도록 해야 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) 6d항에 따라 저작물의 개체 코드 및 해당 소스가 일반 대중에게 무료로 제공되는 위치를 다른 피어에게 알리는 경우 피어 투 피어 전송을 사용하여 개체 코드를 전달합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">소스 코드가 시스템 라이브러리로 해당 소스에서 제외된 객체 코드의 분리 가능한 부분은 객체 코드 작업을 전달하는 데 포함될 필요가 없습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;사용자 제품&quot;은 (1) 일반적으로 개인, 가족 또는 가정의 목적으로 사용되는 유형의 개인 자산을 의미하는 &quot;소비자 제품&quot; 또는 (2) 주거에 통합하기 위해 설계되거나 판매되는 모든 것입니다. 제품이 소비자 제품인지 여부를 결정할 때 의심스러운 경우 보장을 위해 해결해야 합니다. 특정 사용자가 받은 특정 상품에 대해 &quot;일반적인 사용&quot;은 특정 사용자가 제품을 실제로 사용하거나 예상하거나 사용할 것으로 예상되는 방식에 관계없이 해당 제품 클래스의 일반적이거나 일반적인 사용을 나타냅니다. 제품이 상업적, 산업적 또는 비소비자적 용도로 사용되는지 여부에 관계없이 제품은 해당 용도가 제품의 유일한 중요한 사용 모드를 나타내지 않는 한 소비자 제품입니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">사용자 제품에 대한 &quot;설치 정보&quot;는 해당 소스의 수정된 버전에서 해당 사용자 제품에 포함된 작업의 수정된 버전을 설치하고 실행하는 데 필요한 모든 방법, 절차, 인증 키 또는 기타 정보를 의미합니다. 정보는 수정된 목적 코드의 계속적인 기능이 단지 수정이 이루어졌다는 이유만으로 방해되거나 방해받지 않도록 하는 데 충분해야 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">귀하가 사용자 제품에서 또는 함께 또는 특별히 사용하기 위해 이 섹션에 따라 객체 코드 작업을 전달하고 전달이 사용자 제품의 소유 및 사용 권한이 영구적으로 또는 고정된 기간 동안 (거래의 특징에 관계없이) 이 섹션에 따라 전달되는 해당 출처에는 설치 정보가 수반되어야 합니다. 그러나 이 요구 사항은 귀하나 제3자가 사용자 제품에 수정된 객체 코드를 설치할 수 있는 능력을 보유하지 않는 경우 적용되지 않습니다 (예: 저작물이 ROM에 설치된 경우).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">설치 정보 제공 요건에는 수령인이 수정하거나 설치한 저작물 또는 수정 또는 설치된 사용자 제품에 대한 지원 서비스, 보증 또는 업데이트를 계속 제공해야 하는 요건이 포함되지 않습니다. 수정 자체가 네트워크 운영에 중대하고 부정적인 영향을 미치거나 네트워크를 통한 통신에 대한 규칙 및 프로토콜을 위반하는 경우 네트워크에 대한 접속이 거부될 수 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">이 섹션에 따라 전달된 해당 소스 및 제공된 설치 정보는 공개적으로 문서화된 형식이어야 하며(그리고 소스 코드 형식으로 대중이 사용할 수 있는 구현으로) 압축 해제, 읽기 또는 복사시 특별한 비밀번호나 키가 필요하지 않아야 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. 추가 약관.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;추가 권한&quot;은 하나 이상의 조건에서 예외를 둠으로써 이 라이센스의 조건을 보완하는 조건입니다. 전체 프로그램에 적용되는 추가 권한은 해당 법률에 따라 유효한 범위 내에서 본 라이센스에 포함된 것처럼 취급됩니다. 추가 권한이 프로그램의 일부에만 적용되는 경우 해당 부분은 해당 권한에 따라 별도로 사용할 수 있지만 전체 프로그램은 추가 권한에 관계없이 이 라이센스의 적용을 받습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">적용 대상 작업의 사본을 전달할 때 귀하는 선택에 따라 해당 사본 또는 그 일부에서 추가 권한을 제거할 수 있습니다. (특정 경우에 작업을 수정할 때 자체적으로 제거해야 하는 추가 권한이 작성될 수 있습니다.) 귀하는 적절한 저작권 권한이 있거나 부여할 수 있는 해당 작업에 귀하가 추가한 자료에 추가 권한을 부여할 수 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">이 라이센스의 다른 조항에도 불구하고 적용되는 작업에 추가하는 자료에 대해 귀하는 (해당 자료의 저작권 소유자가 승인한 경우) 다음 조건으로 이 라이센스의 조건을 보완할 수 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) 이 라이센스의 섹션 15 및 16의 조건과 다르게 보증을 부인하거나 책임을 제한합니다; 또는</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) 해당 자료 또는 이를 포함하는 저작물에 의해 표시되는 적절한 법적 고지에 명시된 합당한 법적 고지 또는 저자 표시의 보존을 요구합니다; 또는</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) 해당 자료의 출처에 대한 허위 진술을 금지하거나 그러한 자료의 수정된 버전을 원래 버전과 다른 합리적인 방식으로 표시하도록 요구합니다; 또는</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) 자료의 사용 허가자 또는 저자 이름을 홍보 목적으로 사용하는 것을 제한합니다; 또는</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) 일부 상호, 상표 또는 서비스 마크의 사용에 대해 상표법에 따른 권리 부여를 거부합니다; 또는</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) 이러한 계약상 가정이 해당 라이센스 제공자 및 작성자에게 직접 부과하는 모든 책임에 대해 수신자에 대한 책임의 계약적 가정과 함께 자료 (또는 수정된 버전)를 전달하는 사람이 해당 자료의 라이센스 제공자 및 작성자에 대한 면책을 요구합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">다른 모든 비허용 추가 조건은 섹션 10의 의미 내에서 &quot;추가 제한&quot;으로 간주됩니다. 귀하가 받은 프로그램 또는 그 일부에 다음 조건과 함께 본 라이센스가 적용된다는 통지가 포함되어 있는 경우 추가 제한이 있는 경우 해당 용어를 제거할 수 있습니다. 라이센스 문서에 추가 제한 사항이 포함되어 있지만 본 라이센스에 따라 재라이센스 또는 전달을 허용하는 경우, 추가 제한이 해당 라이센스 문서의 조건이 적용되는 적용 작업 자료에 추가할 수 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">이 섹션에 따라 적용되는 저작물에 용어를 추가하는 경우 해당 파일에 적용되는 추가 용어에 대한 설명 또는 해당 용어를 찾을 수 있는 위치를 나타내는 알림을 관련 소스 파일에 배치해야 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">추가 조건 (허용 또는 비허용)은 별도로 서면 라이센스 형식으로 명시되거나 예외로 명시될 수 있습니다. 위의 요구 사항은 어느 쪽이든 적용됩니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. 종료.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">귀하는 본 라이센스에 따라 명시적으로 제공된 경우를 제외하고 해당 저작물을 전파하거나 수정할 수 없습니다. 이를 전파하거나 수정하려는 모든 시도는 무효이며 본 라이센스 (11항의 세 번째 단락에 따라 부여된 특허 라이센스 포함)에 따른 귀하의 권리를 자동으로 종료합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">그러나 이 라이센스의 모든 위반을 중단하면 특정 저작권자의 라이센스는 (a) 저작권자가 명시적이고 최종적으로 라이센스를 종료하지 않는 한 잠정적으로, 그리고 (b) 저작권 보유자가 실패하는 경우 영구적으로 복원됩니다. 중단 후 60일 이전에 합리적인 방법으로 위반 사실을 통지합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">또한 특정 저작권 보유자의 라이센스는 저작권 보유자가 합리적인 수단으로 위반 사실을 통지한 경우 영구적으로 복원되고, 해당 저작권 보유자로부터 본 라이센스 (모든 저작물에 대한) 위반 통지를 받은 것은 이번이 처음이며, 통지를 받은 후 30일 이내에 위반 사항을 시정해야 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">이 섹션에 따른 귀하의 권리 종료는 본 라이센스에 따라 귀하로부터 사본 또는 권리를 받은 당사자의 라이센스를 종료하지 않습니다. 귀하의 권리가 종료되고 영구적으로 복원되지 않은 경우 섹션 10에 따라 동일한 자료에 대한 새로운 라이센스를 받을 자격이 없습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. 사본을 보유하기 위해 승인이 필요하지 않음.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">귀하는 본 프로그램의 사본을 받거나 실행하기 위해 본 라이센스에 동의할 필요가 없습니다. 마찬가지로 사본을 수신하기 위해 P2P 전송을 사용한 결과로만 발생하는 해당 저작물의 부수적 전파는 승인을 요구하지 않습니다. 그러나 이 라이센스 이외의 어떤 것도 해당 저작물을 전파하거나 수정할 수 있는 권한을 부여하지 않습니다. 이 라이센스에 동의하지 않는 경우 이러한 행위는 저작권을 침해합니다. 따라서 해당 저작물을 수정하거나 전파함으로써 귀하는 그렇게 하기 위해 본 라이센스에 동의함을 나타냅니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. 다운스트림 수신자의 자동 라이센스.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">적용되는 저작물을 전달할 때마다 수신자는 본 라이센스에 따라 해당 저작물을 실행, 수정 및 전파할 수 있는 라이센스를 원래 라이센스 제공자로부터 자동으로 받습니다. 귀하는 제3자가 본 라이센스를 준수하도록 강제할 책임이 없습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;법인 거래&quot;는 조직의 통제권을 이전하거나 한 조직의 실질적으로 모든 자산을 이전하거나 조직을 세분화하거나 조직을 병합하는 거래입니다. 적용 대상 저작물의 전파가 법인 거래로 인해 발생하는 경우, 저작물의 사본을 받는 해당 거래의 각 당사자는 이해 당사자의 전임자가 이전 단락에 따라 제공했거나 제공할 수 있었던 작업에 대한 라이센스를 모두 받고, 또한 전임자가 합리적인 노력으로 그것을 가지고 있거나 얻을 수 있는 경우 관심 있는 전임자로부터 작업의 해당 소스를 소유할 권리가 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">귀하는 본 라이센스에 따라 부여되거나 확인된 권리의 행사에 추가 제한을 부과할 수 없습니다. 예를 들어, 귀하는 본 라이센스에 따라 부여된 권리 행사에 대해 라이센스 수수료, 로열티 또는 기타 요금을 부과할 수 없고, 귀하는 프로그램 또는 프로그램의 일부를 제작, 사용, 판매, 판매 제안 또는 수입함으로써 특허 청구가 침해되었다고 주장하는 소송(교차 청구 또는 반소 포함)을 시작할 수 없습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;기여자&quot;는 본 프로그램 또는 프로그램의 기반이 되는 저작물의 사용을 허가하는 저작권 보유자입니다. 이렇게 라이센스가 부여된 저작물을 기여자의 &quot;기여자 버전&quot;이라고 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">기여자의 &quot;필수 특허 청구&quot;는 기여자가 소유하거나 통제하는 모든 특허 청구이며, 이미 취득했거나 이후 취득했는지 여부에 관계없이 본 라이센스에서 허용하는 방식으로 기여자 버전을 제작, 사용 또는 판매함으로써 침해될 수 있습니다. 기여자 버전을 추가로 수정한 결과로만 침해될 수 있는 주장을 포함합니다. 이 정의의 목적에 따라 &quot;제어&quot;에는 이 라이센스의 요구 사항과 일치하는 방식으로 특허 하위 라이센스를 부여할 수 있는 권리가 포함됩니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">각 기여자는 기여자 버전의 콘텐츠를 만들고, 사용하고, 판매하고, 판매 제안, 수입 및 달리 실행, 수정 및 전파할 수 있는 기여자의 필수 특허 청구에 따라 비독점적이고 전세계적이며 로열티가 없는 특허 라이센스를 부여합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">다음 세 단락에서 &quot;특허 라이센스&quot;는 명시적 합의 또는 약속이지만 명시적이지만 특허를 집행하지 않기로 한 명시적 동의 또는 약속입니다 (예: 특허를 실행하기 위한 명시적 허가 또는 특허 침해 소송을 제기하지 않겠다는 서약). 당사자에게 그러한 특허 라이센스를 &quot;부여한다&quot;는 것은 당사자에 대해 특허를 집행하지 않기로 합의하거나 약속하는 것을 의미합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">고의로 특허 라이센스에 의존하여 적용 대상 작업을 전달하고 작업의 해당 소스를 공개적으로 사용 가능한 네트워크 서버 또는 쉽게 접속할 수 있는 기타를 통해 이 라이센스의 조건에 따라 누구나 무료로 복사할 수 없는 경우 다음 중 하나를 수행해야 함을 의미합니다 (1) 해당 소스를 사용 가능하게 하거나 (2) 이 특정 작업에 대한 특허 라이센스의 혜택을 박탈하도록 준비하거나 (3) 이 라이센스는 다운스트림 수신자에게 특허 라이센스를 확장합니다. &quot;고의로 의존&quot;한다는 것은 특허 라이센스의 경우 한 국가에서 해당 저작물을 전달하거나 수신자가 해당 국가에서 해당 저작물을 사용한다는 실제 지식을 가지고 있음을 의미하고, 귀하가 유효하다고 믿을 만한 이유가 있는 해당 국가에서 하나 이상의 식별 가능한 특허를 침해할 수 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">단일 거래 또는 약정에 따라 또는 이와 관련하여 귀하가 해당 저작물의 양도 조달을 통해 전달하거나 전파하고 해당 저작물을 받는 일부 당사자에게 사용, 전파, 수정 권한을 부여하는 특허 라이센스를 부여하는 경우 또는 해당 저작물의 특정 사본을 전달하면 귀하가 부여한 특허 라이센스가 해당 저작물 및 이를 기반으로 하는 작업의 모든 수신자에게 자동으로 확장됩니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">특허 라이센스가 적용 범위 내에 포함되지 않거나, 본 라이세센스에 따라 구체적으로 부여된 하나 이상의 권리의 행사를 금지하거나, 미행사를 조건으로 하는 경우 &quot;차별적&quot;입니다. 귀하가 소프트웨어 배포 사업에 종사하는 제3자와 약정의 당사자인 경우 해당 작업을 전달할 수 없으며, 이에 따라 귀하의 작업 전달 활동 범위에 따라 제3자에게 지불하고, 제3자가 귀하로부터 해당 작업을 받을 당사자에게 차별적 특허 라이센스를 부여하는 경우 (a) 귀하가 전달한 해당 저작물의 사본 (또는 이러한 사본으로 만든 사본)과 관련하여, 또는 (b) 귀하가 해당 약정을 체결하지 않는 한, 주로 해당 저작물을 포함하는 특정 제품 또는 편집물과 관련하여, 또는 2007년 3월 28일 이전에 특허 라이센스가 부여되었습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">이 라이센스의 어떠한 내용도 관련 특허법에 따라 귀하에게 제공될 수 있는 묵시적 라이센스 또는 침해에 대한 기타 방어를 배제하거나 제한하는 것으로 해석되지 않습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. 타인의 자유에 대한 양도 금지.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">본 라이센스의 조건과 모순되는 조건이 귀하에게 부과되는 경우 (법원 명령, 합의 또는 기타 방식에 관계없이), 이는 귀하가 본 라이센스의 조건에서 면제되는 것은 아닙니다. 본 라이센스에 따른 귀하의 의무와 기타 관련 의무를 동시에 충족하기 위해 적용 대상 작업을 전달할 수 없는 경우 결과적으로 귀하는 이를 전혀 전달하지 않을 수 있습니다. 예를 들어, 귀하가 프로그램을 전달하는 대상으로부터 추가 전달을 위해 로열티를 징수해야 하는 조건에 동의하는 경우 이러한 조건과 본 라이센스를 모두 충족할 수 있는 유일한 방법은 프로그램 전달을 완전히 자제하는 것입니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. GNU 아페로 일반 공개 라이센스와 함께 사용</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">이 라이센스의 다른 조항에도 불구하고, 귀하는 GNU 아페로 일반 공개 라이센스 버전 3에 따라 라이센스가 부여된 저작물과 관련된 작업을 하나의 결합된 작업으로 연결하거나 결합하고 결과 작업을 전달할 수 있는 권한이 있습니다. 이 라이센스의 조건은 적용되는 작업 부분에 계속 적용되지만 네트워크를 통한 상호 작용에 관한 GNU 아페로 일반 공개 라이센스, 섹션 13의 특별 요구 사항은 그대로 결합에 적용됩니다..</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. 이 라이센스의 개정된 버전.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">자유 소프트웨어 재단은 때때로 GNU 일반 공개 라이센스의 개정판 및/또는 새 버전을 게시할 수 있습니다. 이러한 새 버전은 현재 버전과 정신이 비슷하지만 새로운 문제나 우려 사항을 해결하기 위해 세부적으로 다를 수 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">각 버전에는 고유한 버전 번호가 부여됩니다. 프로그램이 GNU 일반 공개 라이센트 &quot;또는 이후 버전&quot;의 특정 번호 버전을 지정하는 경우 적용되는 경우, 귀하는 해당 번호가 있는 버전 또는 자유 소프트웨어 재단에서 발행한 이후 버전의 이용 약관을 따를 수 있습니다. 프로그램에서 GNU 일반 공개 라이센스의 버전 번호를 지정하지 않은 경우 자유 소프트웨어 재단에서 발행한 모든 버전을 선택할 수 있습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">프로그램에서 프록시가 사용할 수 있는 GNU 일반 공개 라이센스의 향후 버전을 결정할 수 있도록 지정하는 경우 해당 프록시의 버전 수락에 대한 공개 성명은 귀하가 프로그램에 대해 해당 버전을 선택할 수 있는 권한을 영구적으로 부여합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">최신 라이센스 버전은 추가 또는 다른 권한을 부여할 수 있습니다. 그러나 이후 버전을 따르기로 선택한 결과 작성자 또는 저작권 보유자에게 추가 의무가 부과되지 않습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. 보증 부인.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">관련 법률이 허용하는 한도 내에서 프로그램에 대한 보증은 없습니다. 저작권 소유자 및/또는 기타 당사자가 &quot;있는 그대로&quot; 프로그램을 제공하는 서면에 달리 명시된 경우를 제외하고 상품성 및 특정 목적에의 적합성에 대한 묵시적 보증을 포함하되 이에 국한되지 않는 모든 종류의 명시적 또는 묵시적 보증 없이. 프로그램의 품질과 성능에 대한 모든 위험은 귀하에게 있습니다. 프로그램에 결함이 있는 것으로 판명되면 필요한 모든 서비스, 수리 또는 수정 비용은 귀하가 부담해야 합니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. 책임의 제한.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">관련 법률에서 요구하거나 서면으로 동의하지 않는 한 어떠한 경우에도 저작권 보유자 또는 위에서 허용한 대로 프로그램을 수정 및/또는 전달하는 기타 당사자는 모든 일반 또는 기타 손해를 포함하여 귀하에게 손해에 대해 책임을 지지 않습니다. 프로그램 사용 또는 사용 불가능으로 인해 발생하는 손해(데이터 손실 또는 부정확하게 렌더링되는 데이터 또는 손실 또는 귀하 또는 제3자가 유지하는 손실 또는 다른 프로그램과 함께 작동하는 프로그램의 실패를 포함하되 이에 국한되지 않음) 그러한 보유자 또는 다른 당사자는 그러한 손해의 가능성에 대해 조언을 받았습니다.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. 섹션 15 및 16의 해석.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">위에 제공된 보증 부인 및 책임 제한이 해당 조건에 따라 현지 법적 효력을 부여할 수 없는 경우, 보증 또는 가정을 제외하고, 검토 법원은 프로그램과 관련된 모든 민사 책임의 절대 면제에 가장 근접한 현지 법률을 적용합니다. 비용에 대한 대가로 프로그램 사본이 함께 제공됩니다.</span></p></body></html> About Development 개발 정보 "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. "pktiuk" (2020년 8월 이후) 저는 이 매우 유용한 소프트웨어가 버려지지 않도록 이 프로젝트를 계속 지원하고 가능한 한 널리 접속할 수 있도록 하기로 결정했습니다. "juliagoda" (2018년 3월부터 2020년까지) 게임패드를 지원하지 않는 내가 좋아하는 오래된 게임만 하고 싶어서 이 프로젝트 (키보드 키와 마우스 버튼을 리눅스의 연결된 게임패드에 매핑)가 가장 적절하고 최근에 발견되었습니다. 그러나 인터넷에서 그러한 응용 프로그램을 잘못 선택하고 제대로 컴파일되지 않았기 때문에 프로젝트를 구출하기로 결정했습니다. 그러나 일단 작업을 마치면 (게임을 즐길 수 있을 만큼) 이 코드를 다른 사람들과 공유할 생각을 했습니다. 물론 과거 프로그래머에 대한 모든 정보는 보관됩니다. "Ryochan7" (2012년 12월 30일부터 2017년까지), 저는 여가 시간에 AntiMicro 작업을 하고 있습니다. 원래 QJoyPad의 포크로 시작했고 적절한 이벤트 중심 프로그래밍을 배우는 방법은 원래 의도했던 것보다 훨씬 더 큰 것으로 바뀌었습니다. 새로운 기술을 배우고 KB+M 에뮬레이션의 영역에 대해 더 많이 알아보고 금요일 밤에 키보드에 머리를 부딪히는 데 많은 시간을 보냈지만 전반적으로 재미있고 풍부한 경험이었습니다. 이 프로그램의 필요성은 기본 컨트롤러 지원을 제공하지 않는 여러 게임을 플레이하기 위해 윈도우즈에서 유사한 프로그램을 사용하는 데서 비롯되었습니다. 리눅스에 몇 가지 대안이 있었지만 KB+M 에뮬레이션을 사용하여 플레이하고 싶은 게임을 실제로 즐기기에 기능이나 게임 내 컨트롤 면에서 충분히 좋다고 느낀 것은 없었습니다. QJoyPad는 예전에 많이 사용하던 메인 프로그램이었지만, 제가 꼭 필요하다고 생각하는 기본적인 기능은 제공하지 못했습니다. 프로젝트는 몇 년 동안 업데이트되지 않았기 때문에 죽었습니다. 그래서 직접 만들기로 결정했습니다. 그 이후로 나는 다른 프로그램이 잘하는 것을 찾아 개선하려고 노력했습니다. 또한 그 과정에서 몇 가지 멋진 트릭을 발견했으며 일부 게임에서 기본 게임패드 컨트롤이 구현되는 방식에 대해 제가 정말 알고 싶었던 것보다 더 많이 배웠습니다. 이 프로그램이 개선될 수 있는 부분이 분명히 있지만 이 프로그램은 기본 컨트롤러 지원을 제공하지 않는 구형 및 일부 최신 게임을 플레이하는 데 최고의 게임 내 제어 경험을 제공한다는 것을 알았습니다. 이 프로그램의 개발은 더 이상 나에게 높은 우선 순위가 아닙니다. 이는 주로 스팀 컨트롤러가 Xbox 360 컨트롤러를 사용하는 것과 비교하여 PC 게임을 플레이하는 작업에 꽤 잘 작동한다는 사실 때문입니다. 하지만 이 프로그램이 당분간 존재해야 할 이유가 있는 것 같습니다. --- 2016년 5월 24일 현재 이 프로젝트는 https://github.com/AntiMicro/antimicro 로 이동했습니다. 또한 Travis가 다른 관심사와 우선 순위를 갖고 있기 때문에 프로젝트 관리가 Travis(Ryochan7)에서 AntiMicro 조직으로 넘어갔습니다. 다음으로, 프로젝트는 antimicroX 프로젝트의 juliagoda에 의해 2018년부터 계속되었습니다. 이후 프로젝트는 다시 https://github.com/AntiMicroX/antimicrox 로 이동되었으며 pktiuk에서 만든 AntiMicroX 조직에서 유지 관리를 계속하고 있습니다. Copyright: 2013 - 2022 저작권: 2013 - 2022 License 라이센스 Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 이벤트 핸들러 사용: %1 AddEditAutoProfileDialog Auto Profile Dialog 자동 프로파일 대화상자 Pro&file: 프로파일(&F): Browse 찾아보기 Window: 창: Select Window. Click on the appropriate application window and the application file path will be populated in the form. 창을 선택합니다. 해당 응용 프로그램 창을 클릭하면 응용 프로그램 파일 경로가 양식에 채워집니다. Detect Window Properties 창 속성 감지 &Class: 등급(&C): T&itle: 제목(&I): set partial title 부분 제목 설정 Application: 응용 프로그램: Select 선택 De&vices: 장치(&V): Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. 지정된 장치에 대해 불러오는 기본 프로파일로 이 프로파일을 선택합니다. 모든 기본 프로파일 옵션 대신 선택 항목이 사용됩니다. Set as Default for Controller 컨트롤러의 기본값으로 설정 A different profile is already selected as the default for this device. 다른 프로파일이 이미 이 장치의 기본값으로 선택되어 있습니다. Current (%1) 현재 (%1) Open Config 구성 열기 Select Program 프로그램 선택 Programs (*.exe) 프로그램 (*.exe) Please use the main default profile selection. 기본 프로파일 선택을 사용하세요. Main Profile 주요 프로파일 Already selected 이미 선택됨 Chosen Profile 선택한 프로파일 The selection will be used instead of the all default profile option. 모든 기본 프로파일 옵션 대신 선택 항목이 사용됩니다. Please select a window by using the mouse. Press Escape if you want to cancel. 마우스를 이용하여 창을 선택해주세요. 취소하려면 Esc 키를 누르세요. Capture Application Window 애플리케이션 창 캡쳐 Could not obtain information for the selected window. 선택한 창에 대한 정보를 얻을 수 없습니다. Application Capture Failed 응용 프로그램 캡처 실패 Profile file path is invalid. 프로파일 파일 경로가 잘못되었습니다. No window matching property was specified. 창 일치 속성이 지정되지 않았습니다. Program path is invalid or not executable. 프로그램 경로가 잘못되었거나 실행할 수 없습니다. File is not an .exe file. 파일이 .exe 파일이 아닙니다. No window matching property was selected. 창 일치 속성이 선택되지 않았습니다. AdvanceButtonDialog Advanced 고급 Assignments 할당 Toggle 전환 Turbo 터보 Set Selector 선택기 설정 Blank or KB/M 공백 또는 KB/M Hold 유지 Pause 정지 Cycle 주기 Distance 거리 Insert 삽입 Delete 삭제 Clear All 모두 지우기 Time: 시간: 0.01s 0.01 초 0s 0 초 Insert a pause that occurs in between key presses. 키 누름 사이에 발생하는 일시 중지를 삽입합니다. Release 개정 Insert a new blank slot. 새로운 빈 슬롯을 삽입합니다. Delete a slot. 슬롯을 삭제합니다. Clear all currently assigned slots. 현재 할당된 모든 슬롯을 지웁니다. Specify the duration of an inserted Pause or Hold slot. 삽입된 일시 중지 또는 유지 슬롯의 지속 시간을 지정합니다. 0m 0 분 &Mouse Speed Mod: 마우스 속도 모드(&M): Specify the range past an axis dead zone in which a sequence of actions will execute. 일련의 동작이 실행될 축 사각지대를 지나는 범위를 지정합니다. Distance: 거리: % % Mouse Mod 마우스 모드 Press Time 시간 누름 Delay 지연 Execute 실행 Load 불러오기 Set Change 변경 설정 Text Entry 텍스트 입력 Join 연결 Split 분할 Placeholder 자리표시자 0 0 Set the percentage that mouse speeds will be modified by. 마우스 속도가 수정되는 비율을 설정합니다. Auto Reset Cycle After 다음 후 자동 재설정 주기 seconds Executable: 실행 파일: ... ... Arguments: 인수: Enabled 활성화됨 Mode: 모드: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>보통: 선택한 비율만큼 버튼을 반복적으로 눌렀다 떼세요.</p><p>경사도: 축이 이동한 거리에 따라 버튼 누름 및 버튼 해제 지연을 수정합니다. 속도는 동일하게 유지됩니다.</p><p>펄스: 초당 버튼을 눌렀다 떼는 횟수를 수정합니다. 버튼 지연은 동일하게 유지됩니다.</p></body></html> Normal 보통 Gradient 경사도 Pulse 펄스 Delay: 지연: 0.10s 0.10 초 Rate: 속도: 10.0/s 10.0/초 Disabled 비활성화됨 Select Set 1 One Way 설정 1 한 방향 선택 Select Set 1 Two Way 설정 1 두 방향 선택 Select Set 1 While Held 누른 상태에서 설정 1 선택 Select Set 2 One Way 설정 2 한 방향 선택 Select Set 2 Two Way 설정 2 두 방향 선택 Select Set 2 While Held 누른 상태에서 설정 2 선택 Select Set 3 One Way 설정 3 한 방향 선택 Select Set 3 Two Way 설정 3 두 방향 선택 Select Set 3 While Held 누른 상태에서 설정 3 선택 Select Set 4 One Way 설정 4 한 방향 선택 Select Set 4 Two Way 설정 4 두 방향 선택 Select Set 4 While Held 누른 상태에서 설정 4 선택 Select Set 5 One Way 설정 5 한 방향 선택 Select Set 5 Two Way 설정 5 두 방향 선택 Select Set 5 While Held 누른 상태에서 설정 5 선택 Select Set 6 One Way 설정 6 한 방향 선택 Select Set 6 Two Way 설정 6 두 방향 선택 Select Set 6 While Held 누른 상태에서 설정 6 선택 Select Set 7 One Way 설정 7 한 방향 선택 Select Set 7 Two Way 설정 7 두 방향 선택 Select Set 7 While Held 누른 상태에서 설정 7 선택 Select Set 8 One Way 설정 8 한 방향 선택 Select Set 8 Two Way 설정 8 두 방향 선택 Select Set 8 While Held 누른 상태에서 설정 8 선택 [NO KEY] [키 할당 없음] sec. 초. /sec. /초. Not checked slots 확인되지 않은 슬롯 To delete slots, you need to select at least one 슬롯을 삭제하려면 하나 이상의 슬롯 선택 To insert slots, you need to select at least one 슬롯을 삽입하려면 하나 이상의 슬롯 선택 Unknown current slot 알 수 없는 현재 슬롯 Click on chosen slots before joining them 합치기 전에 선택한 슬롯 클릭 Not enough slots 슬롯이 충분하지 않음 It's impossible to join slots. Add at least one other slot. 슬롯에 합치는 것은 불가능합니다. 하나 이상의 다른 슬롯을 추가하세요. Not selected slots 선택되지 않은 슬롯 It's impossible to join slots. Select at least two slots before joining them 슬롯에 합치는 것은 불가능합니다. 결합하기 전에 최소 2개의 슬롯 선택 Only keyboard slots 키보드 슬롯만 It's only possible to join simple and mix keyboard slots 단순 및 혼합 키보드 슬롯만 결합할 수 있음 It's impossible to split slots. Add at least one other slot. 슬롯 분할은 불가능합니다. 하나 이상의 다른 슬롯을 추가하세요. Not selected slot 선택되지 않은 슬롯 Select your slot before splitting. 분할하기 전에 슬롯을 선택하세요. Too many mix slots 너무 많은 혼합 슬롯 Select one mix slot. 하나의 혼합 슬롯을 선택합니다. Only mix slots 혼합 슬롯만 It's only possible to split mix slot. 혼합 슬롯 분할만 가능합니다. Empty execution path 비어 있는 실행 경로 Line for execution file path is empty. Fill the first line before you are going to add a slot. 실행 파일 경로에 대한 줄이 비어 있습니다. 슬롯을 추가하기 전에 첫 번째 줄을 채우세요. File doesn't exist 파일이 존재하지 않음 There is no such file locally, that could be executed. Check the file on your system 로컬에 실행할 수 있는 파일이 없습니다. 시스템의 파일 확인 Set %1 설정 %1 Select Set %1 설정 % 1을(를) 선택 One Way 한 방향 Two Way 두 방향 While Held 누른 상태 Choose Executable 실행 파일 선택 Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. 주기 동작을 지난 슬롯은 다음 버튼을 누를 때 실행됩니다. 시퀀스에서 파티션을 생성하기 위해 여러 주기를 추가할 수 있습니다. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. 지정된 시간만큼 다음 슬롯이 활성화되는 시간을 지연시킵니다. 지연 전에 활성화된 슬롯은 지연 시간이 지난 후에도 활성 상태를 유지합니다. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. 거리 동작은 축이 지정된 데드 존을 지나 특정 범위로 이동할 때만 이후의 슬롯이 실행되도록 지정합니다. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. 유지 동작을 삽입하세요. 버튼이 지정된 간격을 지나고 있는 경우에만 동작 이후의 슬롯이 실행됩니다. Chose a profile to load when this slot is activated. 이 슬롯이 활성화될 때 불러올 프로파일을 선택하세요. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. 마우스 모드 동작은 동작이 처리되는 동안 지정된 비율만큼 모든 마우스 속도 설정을 수정합니다. 이것은 저격하는 동안 마우스를 느리게 하는 데 유용할 수 있습니다. Specify the time that keys past this slot should be held down. 이 슬롯을 지나간 키를 누르고 있어야 하는 시간을 지정합니다. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. 개정 동작을 삽입하세요. 동작 후의 슬롯은 버튼이 지정된 간격을 초과하여 누르고 있는 경우 버튼을 놓은 후에만 실행됩니다. Change to selected set once slot is activated. 슬롯이 활성화되면 선택한 설정으로 변경합니다. Full string will be typed when a slot is activated. 슬롯이 활성화되면 전체 문자열이 입력됩니다. Execute program when slot is activated. 슬롯이 활성화되면 프로그램을 실행합니다. Choose Profile 프로파일 선택 Config Files (*.amgp *.xml) 구성 파일 (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment 스틱/패드 할당 Sticks 스틱 DPads 십자 패드 Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. 참고: 이 창은 antimicro 2.0 이전에 만들어진 프로필과의 역호환성을 위한 것입니다. 버전 2.0부터는 게임 컨트롤러 매핑 창을 사용하는 것이 좋습니다. %1 (Joystick %2) %1 (조이스틱 %2) Stick 1 스틱 1 Enabled 활성화됨 Assign 할당 X Axis: X 축: Y Axis: Y 축: Stick 2 스틱 2 Number of Physical DPads: %1 물리적 십자 패드 수: %1 Virtual DPad 1 가상 십자 패드 1 Up: 위쪽: Down: 아래쪽: Left: 왼쪽: Right: 오른쪽: Axis %1 축 %1 Axis %1 - 축 %1 - Axis %1 + 축 %1 + Button %1 버튼 %1 Move stick 1 along the X axis X 축을 따라 스틱 1을 이동 Move stick 1 along the Y axis Y 축을 따라 스틱 1을 이동 Move stick 2 along the X axis X 축을 따라 스틱 2를 이동 Move stick 2 along the Y axis Y 축을 따라 스틱 2를 이동 Press a button or move an axis 버튼을 누르거나 축을 이동 AxisEditDialog Axis Mouse (Horizontal) 마우스 (수평) Mouse (Inverted Horizontal) 마우스 (반전된 수평) Mouse (Vertical) 마우스 (수직) Mouse (Inverted Vertical) 마우스 (반전된 수직) Arrows: Up | Down 화살표: 위쪽 | 아래쪽 Arrows: Left | Right 화살표: 왼쪽 | 오른쪽 Keys: W | S 키: W | S Keys: A | D 키: A | D NumPad: KP_8 | KP_2 숫자 키패드: KP_8 | KP_2 NumPad: KP_4 | KP_6 숫자 키패드: KP_4 | KP_6 None 없음 Set the value to use as the limit for an axis. Useful for a worn out analog stick. 축의 한계로 사용할 값을 설정합니다. 마모된 아날로그 스틱에 유용합니다. Negative Half Throttle 음의 하프 스로틀 Positive Half Throttle 양의 하프 스로틀 Haptic Trigger: 햅틱 트리거: Name: 이름: Specify the name of an axis. 축의 이름을 지정합니다. Mouse Settings 마우스 설정 Set the value of the dead zone for an axis. 축의 데드존 값을 설정합니다. Presets: 사전 설정: Dead Zone: 데드 존: Max Zone: 최대 구역: [NO KEY] [키 할당 없음] Throttle setting that determines the behavior of how to interpret an axis hold or release. 축 고정 또는 해제를 해석하는 방법의 동작을 결정하는 스로틀 설정입니다. Negative Throttle 음의 스로틀 Normal 보통 Positive Throttle 양의 스로틀 Current Value: 현재 값: Set 설정 Set %1 설정 %1 Left Mouse Button 왼쪽 마우스 버튼 Right Mouse Button 오른쪽 마우스 버튼 Click 클릭 Rigid 고정 Rigid Gradient 고정 경사도 Vibration 진동 ButtonEditDialog Dialog 대화상자 To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab 새 할당을 하려면 아무 키보드 키나 누르거나 키보드 또는 마우스 탭에서 버튼 클릭 Placeholder 자리 표시자 Toggle 전환 Enables a key press or release to only occur when a controller button is pressed. 컨트롤러 버튼을 눌렀을 때만 키를 누르거나 떼도록 합니다. Enables rapid key presses and releases. Turbo controller. 빠른 키 누름 및 해제를 가능하게 합니다. 터보 컨트롤러입니다. Turbo 터보 Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs 기억하세요, 이러한 키패드가 컴퓨터에 연결되어 있지 않거나 데스크탑 PC와 같이 내장되어 있지 않으면 작동하지 않습니다. Attach the numeric keypad 숫자 키패드 부착 Last keyboard/mouse button: 마지막 키보드/마우스 버튼: Slots 슬롯 Na&me: 이름(&M): Specify the name of a button. 버튼의 이름을 지정합니다. Action: 동작: Specify the action that will be performed in game while this button is being used. 이 버튼을 사용하는 동안 게임에서 수행할 동작을 지정합니다. Advanced 고급 Choose your keyboard key 키보드 키 선택 No button 버튼 없음 Last button 마지막 버튼 To change settings for last button, it must be at least one assignment from keyboard to gamepad 마지막 버튼의 설정을 변경하려면 키보드에서 게임패드로의 할당이 하나 이상 있어야 함 To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad 마지막 버튼의 터보 설정을 변경하려면 키보드에서 게임패드로 최소한 하나의 할당이어야 함 No choice 선택 없음 Before you open window with advanced settings, you have to choice a key 고급 설정으로 창을 열기 전에 키 선택 To open advanced dialog, it's needed to map at least one button from keyboard to gamepad 고급 대화 상자를 열려면 키보드에서 게임 패드로 하나 이상의 버튼을 매핑 Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad 게임패드용 키보드에서 설정한 버튼이 없기 때문에 버튼용 슬롯을 지울 수 없습니다. 키보드에서 게임패드로 하나 이상의 버튼을 매핑 As last gamepad button has been set 마지막 게임 패드 버튼 설정 Index %1 색인 %1 Calibration Form 양식 Input to calibrate: 보정할 입력: Steps 단계 Z Z TextLabel 텍스트레이블 X X gain 이점 offset 오프셋 Y Y Start calibration 보정 시작 Close 닫기 Reset settings 설정 재설정 Save 저장 Calibration 보정 Gyroscope 자이로스코프 Accelerometer 가속도계 Selected device doesn't have any inputs to calibrate. 선택한 장치에 보정할 입력이 없습니다. Calibration was not saved for the preset. Do you really want to continue? 사전 설정에 대한 보정이 저장되지 않았습니다. 계속하겠습니까? Do you really want to reset calibration of current device? 현재 장치의 보정을 재설정하겠습니까? Accelerometer calibration sets the neutral controller orientation. 가속도계 보정은 중립 컨트롤러 방향을 설정합니다. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. 자이로스코프 보정은 센서 오프셋을 수정합니다. 이렇게 하면 컨트롤러가 움직이지 않는 상태일 때 커서 이동이 방지됩니다. Calibration completed. 보정이 완료되었습니다. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. 오프셋 보정이 완료되었습니다. 이점 보정을 계속하려면 "보정 계속하기"를 클릭하세요. Hold the controller in the desired neutral position and press continue. 컨트롤러를 원하는 중립 위치에 놓고 계속을 누릅니다. Calibrating accelerometer 가속도계 보정 Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. 가속도계 데이터 수집 중... 컨트롤러를 가만히 잡고 계세요. 최대 %1 초가 걸릴 수 있습니다. Place the controller at rest, e.g. put it on the desk, and press continue. 컨트롤러를 움직이지 않는 상태로 둡니다. 예를 들어 책상 위에 놓고 계속을 누릅니다. Calibrating gyroscope 자이로스코프 보정 Collecting gyroscope data... This can take up to %1 seconds. 자이로스코프 데이터 수집 중... 최대 %1 초가 걸릴 수 있습니다. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. 이제 스틱을 다른 방향으로 최대로 여러 번 움직였다가 다시 중앙으로 이동합니다. 최대 %1 초가 소요될 수 있습니다. Calibrating stick 스틱 보정 중 Continue calibration 보정 계속하기 Now move the stick in full circles for several times. This can take up to %1 seconds. 이제 스틱을 여러 번 원을 그리며 움직입니다. 최대 %1 초가 소요될 수 있습니다. Calibration was saved for the preset. Do you really want to reset settings? 사전 설정에 대한 보정이 저장되었습니다. 설정을 재설정하겠습니까? CapturedWindowInfoDialog Captured Window Properties 캡처된 창 속성 Information About Window 창에 대한 정보 Class: 등급: TextLabel 텍스트레이블 Title: 제목: Path: 경로: Match By Properties 속성별 일치 Class 등급 Title 제목 Path 경로 Full Path 전체 경로 File Name 파일 이름 DPadContextMenu Mouse (Normal) 마우스 (보통) Mouse (Inverted Horizontal) 마우스 (반전된 수평) Mouse (Inverted Vertical) 마우스 (반전된 수직) Mouse (Inverted Horizontal + Vertical) 마우스 (반전된 수평 + 수직) Arrows 화살표 Keys: W | A | S | D 키: W | A | S | D NumPad 숫자 키패드 None 없음 Standard 표준 Eight Way 여덟 방향 4 Way Cardinal 4 방향 기본 4 Way Diagonal 4 방향 대각선 Mouse Settings 마우스 설정 DPadEditDialog Dialog 대화상자 Presets: 사전 설정: Mouse (Normal) 마우스 (보통) Mouse (Inverted Horizontal) 마우스 (반전된 수평) Mouse (Inverted Vertical) 마우스 (반전된 수직) Mouse (Inverted Horizontal + Vertical) 마우스 (반전된 수평 + 수직) Arrows 화살표 Keys: W | A | S | D 키: W | A | S | D NumPad 숫자 키패드 None 없음 Dpad Mode: 십자 패드 모드: &Name: 이름(&N): 4 Way Cardinal 4 방향 기본 4 Way Diagonal 4 방향 대각선 DPad Delay: 십자 패드 지연: Time lapsed before a direction change is taken into effect. 방향 변경이 적용되기 전에 경과된 시간입니다. s Specify the name of a dpad. 십자 패드의 이름을 지정합니다. Mouse Settings 마우스 설정 Standard 표준 Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. 표준: 십자 패드가 대각선 영역에 있을 때 2개의 방향 버튼이 활성화된 8 영역 십자 패드입니다. 여덟 방향: 각 방향에 고유한 전용 버튼이 있는 8개 영역 십자 패드입니다. 한 번에 하나의 버튼만 활성화됩니다. 로그라이크 게임에 유용합니다. 4 방향 기본: 4 영역 십자 패드는 십자 패드의 기본 방향에 해당하는 영역을 포함합니다. 메뉴에 유용합니다. 4 방향 대각선: 각 영역이 대각선 영역에 해당하는 4개 영역 십자 패드입니다. Eight Way 여덟 방향 Set 설정 Set %1 설정 %1 EditAllDefaultAutoProfileDialog Default Profile 기본 프로파일 Profile: 프로파일: Browse 찾아보기 Open Config 구성 열기 Profile file path is invalid. 프로파일 파일 경로가 잘못되었습니다. ExtraProfileSettingsDialog Extra Profile Settings 추가 프로파일 설정 Key Press Time: 키 누름 시간: 0.00 ms 0.00 밀리초 Profile Name: 프로파일 이름: s ch GameController Game Controller 게임 컨트롤러 GameControllerDPad DPad 십자 패드 GameControllerMappingDialog Game Controller Mapping 게임 컨트롤러 매핑 <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> <html><head/><body><p>antimicrox는 SDL 2에서 제공하는 <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">게임 컨트롤러 API</span></a>를 사용하여 통합된 표준에 맞게 다양한 게임패드를 추상화하고, 버튼을 할당하려면 아래에서 해당 버튼 행에 대한 매핑 셀을 강조 표시하세요. 그런 다음 버튼을 누르거나 게임패드에서 축을 이동할 수 있으며 셀은 사용할 실제 버튼 또는 축으로 업데이트됩니다.</p><p>antimicrox는 SDL에 로드될 매핑 문자열을 저장하기 위해 지정한 매핑을 사용합니다.</p></body></html> A A B B X X Y Y Back 뒤로 가기 Start 시작 Guide 안내 Left Shoulder 왼쪽 어깨 버튼 Right Shoulder 오른쪽 어깨 버튼 Left Stick Click 왼쪽 스틱 클릭 Right Stick Click 오른쪽 스틱 클릭 Left Stick X 왼쪽 스틱 X Left Stick Y 왼쪽 스틱 Y Right Stick X 오른쪽 스틱 X Right Stick Y 오른쪽 스틱 Y Left Trigger 왼쪽 트리거 Right Trigger 오른쪽 트리거 DPad Up 십자 패드 위쪽 DPad Left 십자 패드 왼쪽 DPad Down 십자 패드 아래쪽 DPad Right 십자 패드 오른쪽 Mapping 매핑 SDL 2 Game Controller Mapping String SDL 2 게임 컨트롤러 매핑 문자열 Last Axis Event: 마지막 축 이벤트: Current Axis Detection Dead Zone: 현재 축 감지 데드 존: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) 게임 컨트롤러 매핑 (%1) (#%2) Discard Controller Mapping? 컨트롤러 매핑을 버리겠습니까? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. 이 컨트롤러에 대한 매핑을 삭제하겠습니까? 폐기된 경우, 모든 조이스틱을 새로 고침하면 컨트롤러가 조이스틱으로 되돌아갑니다. GameControllerSet Back 뒤로 가기 Guide 안내 Start 시작 LS Click 왼쪽 스틱 클릭 RS Click 오른쪽 스틱 클릭 L Shoulder 왼쪽 어깨 버튼 R Shoulder 오른쪽 어깨 버튼 L Trigger 왼쪽 트리거 버튼 R Trigger 오른쪽 트리거 버튼 GameControllerTrigger Trigger 트리거 버튼 JoyAccelerometerButton Up 위쪽 Down 아래쪽 Left 왼쪽 Right 오른쪽 Shock 쇼크 JoyAccelerometerSensor Accelerometer 가속도계 JoyAxis Axis JoyAxisButton Negative Positive Unknown 알 수 없음 Button 버튼 JoyAxisContextMenu Mouse (Horizontal) 마우스 (수평) Mouse (Inverted Horizontal) 마우스 (반전된 수평) Mouse (Vertical) 마우스 (수직) Mouse (Inverted Vertical) 마우스 (반전된 수직) Arrows: Up | Down 화살표: 위쪽 | 아래쪽 Arrows: Left | Right 화살표: 왼쪽 | 오른쪽 Keys: W | S 키: W | S Keys: A | D 키: A | D NumPad: KP_8 | KP_2 숫자 키패드: KP_8 | KP_2 NumPad: KP_4 | KP_6 숫자 키패드: KP_4 | KP_6 None 없음 Mouse Settings 마우스 설정 Left Mouse Button 왼쪽 마우스 버튼 Right Mouse Button 오른쪽 마우스 버튼 JoyButton Processing turbo for #%1 - %2 #%1에 대한 터보 처리 중 - %2 Finishing turbo for button #%1 - %2 버튼 #%1에 대한 터보 종료 중 - %2 Distance change for button #%1 - %2 버튼 #%1의 거리 변경 - %2 Button 버튼 [NO KEY] [키 할당 없음] [Set %1 1W] [설정 %1 1W] [Set %1 2W] [설정 %1 2W] [Set %1 WH] [설정 %1 WH] JoyButtonContextMenu Toggle 전환 Turbo 터보 Clear 지우기 Set Select 선택 설정 Disabled 비활성화됨 Set %1 설정 %1 Set %1 1W 설정 %1 1W Set %1 2W 설정 %1 2W Set %1 WH 설정 %1 WH JoyButtonSlot Mouse 마우스 Up 위쪽 Down 아래쪽 Left 왼쪽 Right 오른쪽 LB 왼쪽 버튼 MB 가운데 버튼 RB 오른쪽 버튼 Pause 정지 Hold 유지 Cycle 주기 Distance 거리 Release 개정 Mouse Mod 마우스 모드 Press Time 누르는 시간 Delay 지연 Load %1 불러오기 %1 Set Change %1 설정 변경 %1 [Text] %1 [텍스트] %1 [Exec] %1 [실행] %1 [NO KEY] [키 할당 없음] JoyControlStick Stick 스틱 JoyControlStickButton Up 위쪽 Down 아래쪽 Left 왼쪽 Right 오른쪽 Button 버튼 JoyControlStickContextMenu Mouse (Normal) 마우스 (보통) Mouse (Inverted Horizontal) 마우스 (반전된 수평) Mouse (Inverted Vertical) 마우스 (반전된 수직) Mouse (Inverted Horizontal + Vertical) 마우스 (반전된 수평 + 수직) Arrows 화살표 Keys: W | A | S | D 키: W | A | S | D NumPad 숫자 키패드 None 없음 Standard 표준 Eight Way 여덟 방향 4 Way Cardinal 4 방향 기본 4 Way Diagonal 4 방향 대각선 Mouse Settings 마우스 설정 JoyControlStickEditDialog Dialog 대화상자 X: X: 0 0 Y: Y: Distance: 거리: Presets: 사전 설정: Mouse (Normal) 마우스 (보통) Mouse (Inverted Horizontal) 마우스 (반전된 수평) Mouse (Inverted Vertical) 마우스 (반전된 수직) Mouse (Inverted Horizontal + Vertical) 마우스 (반전된 수평 + 수직) Arrows 화살표 Keys: W | A | S | D 키: W | A | S | D NumPad 숫자 키패드 None 없음 Stick Mode: 스틱 모드: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 표준: 스틱이 대각선 영역에 있을 때 2개의 방향 버튼이 활성화된 8 영역 스틱입니다. 여덟 방향: 8개 영역 스틱에는 각 방향에 고유한 전용 버튼이 있습니다. 한 번에 하나의 버튼만 활성화됩니다. 로그라이크 게임에 유용합니다. 4 방향 기본: 4 영역 스틱은 스틱의 기본 방향에 해당하는 영역을 포함합니다. 메뉴에 유용합니다. 4 방향 대각선: 스틱의 대각선 영역에 해당하는 각 영역이 있는 4개의 영역 스틱입니다. 4 Way Cardinal 4 방향 기본 4 Way Diagonal 4 방향 대각선 Modifier Zone: 수정기 영역: Dead zone value to use for an analog stick. 아날로그 스틱에 사용할 데드존 값입니다. Value when an analog stick is considered moved 100%. 아날로그 스틱이 100% 움직인 것으로 간주될 때의 값입니다. The area (in degrees) that each diagonal region occupies. 각 대각선 영역이 차지하는 면적 (도)입니다. Square Stick: 정사각형 스틱: Percentage to modify a square stick coordinates to confine values to a circle 값을 원으로 제한하기 위해 정사각형 스틱 좌표를 수정하는 백분율 % % Stick Delay: 스틱 지연: Time lapsed before a direction change is taken into effect. 방향 변경이 적용되기 전에 경과된 시간입니다. s Modifier: 수정 키: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. 스틱이 활성화되어 있는 동안 활성화되는 편집 버튼입니다. 이 버튼은 아날로그 스틱에 걷기/달리기 기능을 할당하는 데 사용할 수 있는 수정 키가 있는 구역을 할당하는 데 유용합니다. PushButton 누름버튼 Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. 수정기 버튼이 활성화되는 임계값입니다. 이 버튼은 아날로그 스틱에 걷기/달리기 기능을 할당하는 데 사용할 수 있는 보조키로 영역을 영역을 할당하는 데 유용합니다. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. 스틱이 임계값 내부 또는 외부에 있을 때 수정자 버튼이 활성화되는지 여부를 정의합니다. 이 버튼은 아날로그 스틱에 걷기/달리기 기능을 할당하는 데 사용할 수 있는 보조키로 영역을 할당하는 데 유용합니다. Invert Modifier Zone 수정기 영역 반전 Na&me: Name: 이름(&M): Specify the name of an analog stick. 아날로그 스틱의 이름을 지정합니다. Mouse Settings 마우스 설정 Standard 표준 Bearing: 베어링: % Safe Zone: % 안전 지역: Eight Way 여덟 방향 Dead Zone: 데드 존: Max Zone: 최대 지역: Diagonal Range: 대각선 범위: Set 설정 Set %1 설정 %1 JoyControlStickModifierButton Modifier 수정 키 JoyDPad DPad 십자 패드 JoyDPadButton Up 위쪽 Down 아래쪽 Left 왼쪽 Right 오른쪽 Button 버튼 JoyGyroscopeButton Pitch Up 피치 업 Pitch Down 피치 다운 Yaw Left 요 왼쪽 Yaw Right 요 오른쪽 Roll Left 롤 왼쪽 Roll Right 롤 오른쪽 JoyGyroscopeSensor Gyroscope 자이로스코프 JoySensorButton Button 버튼 JoySensorContextMenu Mouse Settings 마우스 설정 JoySensorEditDialog Dialog 대화상자 0 0 Acceleration (m/s^2): 가속도 (m/s^2): Pitch (°): 피치 (°): Roll (°): 롤 (°): % Safe Zone: % 안전 영역: Presets: 사전 설정: Dead Zone: 데드 존: Dead zone value to use for an analog sensor. 아날로그 센서에 사용할 데드 존 값입니다. Max Zone: 최대 영역: Value when an analog sensor is considered moved 100%. 아날로그 센서가 100% 이동한 것으로 간주할 때의 값입니다. Diagonal Range: 대각선 범위: The area (in degrees) that each diagonal region occupies. 각 대각선 영역이 차지하는 면적 (도)입니다. Sensor Delay: 센서 지연: Time lapsed before a direction change is taken into effect. 방향 변경이 적용되기 전에 경과된 시간입니다. s Na&me: 이름(&M): Specify the name of an analog sensor. 아날로그 센서의 이름을 지정합니다. Mouse Settings 마우스 설정 Roll (°/s) 롤 (°/s) Pitch (°/s) 피치 (°/s) Yaw (°/s) 요 (°/s) Set 설정 Set %1 설정 %1 JoySensorPreset None 없음 Mouse (Normal) 마우스 (보통) Mouse (Inverted Horizontal) 마우스 (반전된 수평) Mouse (Inverted Vertical) 마우스 (반전된 수직) Mouse (Inverted Horizontal + Vertical) 마우스 (반전된 수평 + 수직) Arrows 화살표 Keys: W | A | S | D 키: W | A | S | D NumPad 숫자 키패드 JoyTabWidget <New> <새로운> Battery level of controller 컨트롤러의 배터리 수준 Remove 제거 Remove configuration from recent list. 최근 목록에서 구성을 제거합니다. Load 불러오기 Load configuration file. 구성 파일을 불러옵니다. Save 저장 Save changes to configuration file. 구성 파일에 변경 사항을 저장합니다. Save As 다른 이름으로 저장 Save changes to a new configuration file. 새로운 구성 파일에 변경 사항을 저장합니다. Sets 설정 Copy from Set 설정에서 복사 Settings 설정 Set 1 설정 1 Set 2 설정 2 Set 3 설정 3 Set 4 설정 4 Set 5 설정 5 Set 6 설정 6 Set 7 설정 7 Set 8 설정 8 Stick/Pad Assign 스틱/패드 할당 Controller Mapping 컨트롤러 매핑 Quick Set 빠른 설정 Names 이름 Toggle button name displaying. 전환 버튼 이름 표시합니다. Pref 기본 설정 Change global profile settings. 전역 프로파일 설정을 변경합니다. Reset 재설정 Revert changes to the configuration. Reload configuration file. 구성 변경 사항을 되돌립니다. 구성 파일을 다시 불러옵니다. Open Config 구성 열기 Config Files (*.amgp *.xml) 구성 파일 (*.amgp *.xml) Config File (*.%1.amgp) 구성 파일 (*.%1.amgp) Do you really want to reset buttons settings for joystick? 조이스틱의 버튼 설정을 재설정하겠습니까? Save Profile Changes? 프로파일 변경 사항을 저장하겠습니까? Changes to the new profile have not been saved. Would you like to save or discard the current profile? 새로운 프로파일에 대한 변경 사항이 저장되지 않았습니다. 현재 프로파일을 저장하거나 삭제하겠습니까? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? 프로파일 "%1"에 대한 변경 사항이 저장되지 않았습니다. 현재 프로파일에 대한 변경 사항을 저장하거나 취소하겠습니까? Sticks 스틱 Sensors 센서 DPads 십자 패드 No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. 버튼이 할당되지 않았습니다. 빠른 설정을 사용하여 버튼에 키를 할당하거나 빈 버튼 숨기기를 비활성화하세요. Set %1: %2 설정 %1: %2 Set %1 설정 %1 Copy Set Assignments 설정 할당 복사 Are you sure you want to copy the assignments and device properties from %1? %1에서 할당 및 장치 속성을 복사하겠습니까? Save Config 구성 저장 Set 설정 Joystick Joystick 조이스틱 JoystickStatusWindow Properties 속성 Details 세부 사항 Name: 이름: %1 %1 Number: 번호: Axes: 축: Buttons: 버튼: Hats: 모자 스위치: Sensors: 센서: Battery: 배터리: Unknown 알 수 없음 GUID: GUID: Game Controller: 게임 컨트롤러: Axes Buttons 버튼 Hats 모자 스위치 Sensors 센서 %1 (#%2) Properties %1 (#%2) 속성 Empty 비어 있음 Low 낮음 Medium 중간 Full 가득 Wired 유선 Different: %1 차이: %1 Accelerometer + Gyroscope 가속도계 + 자이로스코프 Accelerometer 가속도계 Gyroscope 자이로스코프 None 없음 Axis %1 축 %1 Hat %1 모자 스위치 %1 No 없음 Yes MainSettingsDialog Edit Settings 설정 편집 General 일반 Controller Mappings 컨트롤러 매핑 Language 언어 Auto Profile 자동 프로파일 Mouse 마우스 Advanced 고급 <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>프로파일을 불러오거나 새로운 프로파일을 저장할 때 프로그램이 파일 대화상자에서 사용해야 하는 기본 디렉터리를 지정합니다.</p></body></html> Recent Profile Count: 최근 프로파일 수: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>최근 프로파일 목록에 배치할 수 있는 프로파일 수입니다. 0은 프로그램이 표시되는 프로파일 수에 대한 제한을 적용하지 않는 결과를 가져옵니다.</p></body></html> Gamepad Poll Rate: 게임패드 투표율: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. 프로그램이 게임패드에서 새로운 이벤트를 검색하는 데 사용하는 폴링 속도를 변경합니다. 기본값은 10ms입니다. 폴링 속도 값을 줄이면 응용 프로그램이 더 많은 CPU 전력을 사용할 수 있으므로 AntiMicroX를 무인으로 사용하기 전에 사용하는 설정을 테스트하십시오. Hide main window when the main window close button is clicked instead of quitting the program. 프로그램을 종료하는 대신 주요 창 닫기 버튼을 클릭하면 주요 창을 숨깁니다. Close To Tray 트레이 닫기 Have Windows start AntiMicroX at system startup. 시스템 시작 시 윈도우즈가 AntiMicroX를 시작하도록 합니다. Launch At Windows Startup 윈도우즈 시작 시 실행 Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. 트레이 메뉴에서 모든 컨트롤러의 최근 프로파일을 단일 목록으로 표시합니다. 기본값은 하위 메뉴를 사용하는 것입니다. Single Profile List in Tray 트레이의 단일 프로파일 목록 Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. 프로그램을 작업 표시줄로 최소화합니다. 기본적으로 프로그램은 가능한 경우 시스템 트레이로 최소화합니다. Minimize to Taskbar 작업 표시줄로 최소화 This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. 이 옵션을 사용하면 프로그램이 할당된 슬롯이 없는 모든 버튼을 숨길 수 있습니다. 빠른 설정 대화 상자 창은 게임 패드 버튼에 대한 편집 대화상자를 불러오는 데 사용해야 합니다. Hide Empty Buttons 비어 있는 버튼 숨기기 When the program is launched, open the last known profile that was opened during the previous session. 프로그램이 시작되면 이전 세션에서 열린 마지막 알려진 프로파일을 엽니다. Auto Load Last Opened Profile 마지막으로 연 프로파일 자동 불러오기 Only show the system tray icon when the program first launches. 프로그램이 처음 실행될 때만 시스템 트레이 아이콘을 표시합니다. Launch in Tray 트레이에서 실행 Associate .amgp files with AntiMicroX in Windows Explorer. 윈도우즈 탐색기에서 .amgp 파일을 AntiMicroX와 연결합니다. Associate Profiles 프로파일 연결 Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs 이러한 키패드가 컴퓨터에 연결되어 있지 않거나 데스크탑 PC와 같이 내장되어 있지 않으면 작동하지 않는다는 것 기억 Attach the numeric keypad 숫자 키패드 부착 Key Repeat 키 반복 Active keys will be repeatedly pressed when this option is enabled. 이 옵션이 활성화되면 활성 키를 반복해서 누릅니다. Enable 활성화 Specifies how much time should elapse before key repeating begins. 키 반복이 시작되기 전에 경과해야 하는 시간을 지정합니다. Specifies how many times key presses will be performed per seconds. 초당 키 누름 횟수를 지정합니다. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntiMicroX는 기여자들에 의해 다양한 언어로 번역되었습니다. 기본적으로 프로그램은 시스템의 로케일 설정에 따라 적절한 번역을 선택합니다. 그러나 아래 목록에서 선택한 언어에 따라 AntiMicroX가 다른 번역을 불러오게 할 수 있습니다.</p></body></html> Português do Brasil 브라질 포르투갈어 Français 프랑스어 Deutsch 독일어 Italiano 이탈리아어 日本語 일본어 Русский 러시아어 српски / srpski 세르비아어 简体中文 중국어 간체 Español 스페인어 українська 우크라이나어 Polski 폴란드어 History Si&ze: 기록 크기(&Z): Weight Modi&fier: 무게 수정 키(&F): Log File: 로그 파일: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> <html><head/><body><p><span style=" font-style:italic;">참고 지정되지 않은 로그 파일은 콘솔 출력에서 로그를 인쇄할 수 있습니다.</span></p></body></html> Log Level: 로그 수준: None 없음 Error 오류 Warning 경고 Info 정보 Verbose 장황 Debug 디버그 Note: To see the change of log level in console output (not in log file), application restart is required 참고: 로그 파일이 아닌 콘솔 출력에서 로그 수준의 변경 사항을 보려면 응용 프로그램을 다시 시작 Reset 재설정 Class 등급 Pro&file Directory: 프로파일 디렉토리(&F): Show low battery notification 배터리 부족 알림 표시 Show empty battery notification 배터리 방전 알림 표시 Title 제목 Program 프로그램 Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. AntiMicroX가 실행되는 동안 "향상된 포인터 정밀도" 윈도우즈 설정을 비활성화하세요. "향상된 포인터 정밀도"를 비활성화하면 AntiMicroX 내에서 마우스를 더 정확하게 움직일 수 있습니다. Disable Enhance Pointer Precision 포인터 정밀도 향상 비활성화 Smoothing 평활화 Refresh Rate: 새로 고침 빈도: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. 새로 고침 빈도는 마우스 이벤트 사이에 경과할 시간입니다. 이 설정을 편집할 때 프로그램이 더 많은 CPU 전력을 사용하게 되므로 주의하세요. 이 값을 너무 낮게 설정하면 시스템이 불안정해질 수 있습니다. 무인으로 사용하기 전에 설정을 테스트하세요. Spring 스프링 Screen: 화면: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. 스프링 모드에 대해 지정된 화면을 활용합니다. 리눅스에서 기본값은 기본 화면을 사용하는 것입니다. 윈도우즈에서 기본값은 사용 가능한 모든 화면을 사용하는 것입니다. Accel Numerator: 가속도 분자: 0 0 Accel Denominator: 가속도 분모: Accel Threshold: 가속도 임계값: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. 가상 마우스의 가속 값이 다른 프로세스에 의해 변경된 경우, 특히 이전 게임을 종료할 때 가상 마우스에서 사용하는 가속 값을 재설정해야 할 수 있습니다. Reset Acceleration 가속 재설정 Delay: 지연: ms 밀리초 Rate: 빈도: times/s 시간/초 Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. 다음은 저장된 사용자 지정 매핑 목록입니다. 다음 표를 사용하여 매핑을 삭제하거나 매핑을 일시적으로 비활성화할 수 있습니다. SDL에 포함된 매핑을 비활성화할 수도 있습니다. 적절한 조이스틱 GUID로 새로운 행을 삽입하고 비활성화를 선택하세요. 모든 조이스틱을 새로 고치거나 특정 조이스틱의 플러그를 뽑을 때까지 설정이 적용되지 않습니다. GUID GUID Mapping String 매핑 문자열 Disable? 비활성화인가요? Delete 삭제 Default 기본값 English 영어 Active 활성 Devices: 장치: All 모두 Device 장치 Profile 프로파일 Default? 기본값 인가요? Add 추가 Edit 편집 AutoProfile (disabled in Wayland) 자동프로파일 (Wayland에서 비활성화됨) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. 또한 낮은 값을 사용하려는 윈도우즈 사용자는 윈도우즈에서 옵션을 비활성화하지 않은 경우 "포인터 정밀도 향상 비활성화" 확인란도 선택해야 합니다. Select Default Profile Directory 기본 프로파일 디렉토리 선택 Are you sure you want to delete the profile? 프로파일을 삭제하겠습니까? Save Log File As 다른 이름으로 로그 파일 저장 Log Files (*.log) 로그 파일 (*.log) Do you really want to reset setting? 설정을 재설정하겠습니까? Would you like to reset mappings too? 매핑도 재설정하겠습니까? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu 조이스틱을 찾을 수 없음. 조이스틱을 연결한 다음 주 메뉴에서 "조이스틱 업데이트" 옵션을 선택 If events are not seen by a game, please click here to run this application as Administrator. 게임에서 이벤트가 표시되지 않는 경우 여기를 클릭하여 이 응용 프로그램을 관리자로 실행하세요. Update Button 업데이트 버튼 &App 앱(&A) &Options 옵션(&O) He&lp 도움말(&L) &Quit 종료(&Q) Ctrl+Q Ctrl+Q &Update Joysticks 조이스틱 업데이트(&U) Ctrl+U Ctrl+U &Hide 숨기기(&H) Ctrl+H Ctrl+H &About 정보(&A) Ctrl+A Ctrl+A About &Qt Qt 정보(&Q) Ctrl+T Ctrl+T &Properties 속성(&P) Ctrl+P Ctrl+P &Key Checker 키 검사기(&K) Ctrl+K Ctrl+K &GitHub Page 깃허브 페이지(&G) Ctrl+G Ctrl+G S&ettings 설정(&E) Ctrl+S Ctrl+S &Stick/Pad Assign 스틱/패드 할당(&S) Ctrl+X Ctrl+X &Wiki 위키(&W) Ctrl+W Ctrl+W &Issues 문제(&I) Ctrl+I Ctrl+I &Calibration 보정(&C) Ctrl+C Ctrl+C Home Page 홈페이지 (%1) (%1) Open File 파일 열기 Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. 이 프로그램을 관리자로 실행하겠습니까? 일부 게임은 관리자로 실행되므로 antimicro가 관리자로도 실행되지 않는 한 antimicro에서 생성된 이벤트가 해당 게임에서 사용되지 않습니다. 이는 윈도우즈 비스타 이상에서 UAC (사용자 계정 컨트롤) 옵션으로 인한 권한 문제 때문입니다. %1 battery %1 배터리 Battery level is less than %1 배터리 잔량이 %1 미만 Device number: %1 Device name: %2 장치 번호: %1 장치 이름: %2 Update to %1 available %1(으)로 업데이트할 수 있음 Reading old profile 이전 프로파일 읽기 This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 이 프로파일은 컨트롤러의 GUID 번호를 사용합니다. 동일한 게임 컨트롤러에서 사용하기 위해 이 파일에서 GUID 번호를 UniqueID로 변경하겠습니까? 이러한 오래된 파일은 버전 2.25 이후로 antimicrox에서 로드할 수 없음 &Restore 복원(&R) Calibration couldn't be opened 보정을 열 수 없음 You must connect at least one controller to open the window 창을 열려면 하나 이상의 컨트롤러를 연결 Run as Administrator? 관리자로 실행하겠습니까? Failed to elevate program 프로그램 승격 실패 Failed to restart this program as the Administrator 이 프로그램을 관리자로 다시 시작하지 못 함 MouseAxisSettingsDialog Mouse Settings - 마우스 설정 - Set %1 설정 %1 MouseButtonSettingsDialog Mouse Settings - 마우스 설정 - Set %1 설정 %1 MouseControlStickSettingsDialog Mouse Settings 마우스 설정 Set %1 설정 %1 MouseDPadSettingsDialog Mouse Settings 마우스 설정 Set %1 설정 %1 MouseSensorSettingsDialog Mouse Settings 마우스 설정 Set %1 설정 %1 MouseSettingsDialog Mouse Settings 마우스 설정 Mouse Mode: 마우스 모드: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. 커서 모드는 축을 이동하는 정도 또는 버튼을 눌렀는지에 따라 현재 위치를 기준으로 화면 주위에서 마우스 커서를 이동하는 데 사용됩니다. 스프링 모드는 축을 이동하는 정도에 따라 화면 중앙에서 마우스 커서를 이동시키는 방식입니다. 축이 다시 데드존으로 이동하면 마우스 커서는 화면 중앙으로 돌아갑니다. Cursor 커서 Spring 스프링 Acceleration: 가속: Enhanced Precision 향상된 정밀도 Linear 선형 Quadratic 2차 Cubic 3차 Quadratic Extreme 2차 극단 Power Function 멱함수 Easing Quadratic 완화 2차 Easing Cubic 완화 3차 Mouse Speed Settings 마우스 속도 설정 Enable to change the horizontal and vertical speed boxes at the same time. 수평 및 수직 속도 상자를 동시에 변경할 수 있습니다. Change Together 함께 변경 Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. 가속 곡선이 생성하는 것 이상으로 마우스 움직임에 더 많은 가속을 추가하기 위한 옵션입니다. 하나의 게임패드 폴에서 축이 얼마나 빨리 이동하는지에 따라 가속이 추가됩니다. 이는 일반적인 게임패드 아날로그 스틱을 사용하여 사용할 수 있는 매우 제한된 입력 범위의 일부 문제를 해결하는 데 도움을 주기 위한 것입니다. Delta Acceleration 델타 가속 &Multiplier: 승수(&M): Mi&n Threshold: 최소 한계점(&N): 1 = 20 pps 1 = 20 픽섹/초 Wheel Hori. Speed: 휠 수평. 속도: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. 시뮬레이션된 초당 노치 수에 따라 수평 마우스 휠 이동에 사용되는 속도를 설정합니다. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. 초당 시뮬레이션된 노치 수에 따라 수직 마우스 휠 이동에 사용되는 속도를 설정합니다. Sensitivit&y: 민감도(&Y): For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. 멱함수 가속 곡선의 경우입니다. 곡선 감도에 사용할 계수를 지정합니다. 값이 1.0보다 크면 축의 하단에서 마우스 움직임이 더 빠르게 가속됩니다. Easing Duration: 완화 기간: s Highest value to accelerate mouse movement by 마우스 움직임을 가속화하는 가장 높은 값 x x Start %: 시작 %: Acceleration begins at this percentage of the base multiplier 가속은 기본 승수의 이 백분율에서 시작 Minimum amount of axis travel required for acceleration to begin 가속을 시작하는 데 필요한 최소 축 이동량 Max Threshold: 최대 한계점: Maximum axis travel before acceleration has reached the multiplier value 가속이 승수 값에 도달하기 전의 최대 축 이동 E&xtra Duration: 추가 기간(&X): Curve: 곡선: Ease Out Sine Ease Out Sine Ease Out Quad Ease Out Quad Ease Out Cubic Ease Out Cubic Release Radius: 개정 반경: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. 스프링 영역이 비상대 스프링으로 설정된 마우스 위치를 기준으로 하도록 지정합니다. Relative 비교 Mouse Status 마우스 상태 X: X: 0 (0 pps) 0 (0 픽셀/초) Y: Y: 1 = 1 notch(es)/s 1 = 1 노치/초 Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. 향상된 기능: 마우스가 축의 낮은 쪽에서는 느리게 움직이고 높은 쪽에서는 빠르게 움직이는 3계층 곡선입니다. 선형: 마우스가 축에 비례하여 움직입니다. 2차: 마우스가 저역에서 천천히 가속됩니다. 3차: 마우스가 2차보다 느리게 가속됩니다. Quadratic Extreme: 95% 축 이동에 도달하면 마우스 속도를 1.5배 높입니다. 멱함수: 더 많은 사용자 정의 곡선 옵션을 허용합니다. 2차 완화: 2차 곡선을 사용하여 일정 기간 동안 축 높이 끝이 점차 가속됩니다. Easing Cubic: 축 하이 엔드는 3차 곡선을 사용하여 일정 기간 동안 점진적으로 가속됩니다. Hori&zontal Speed: 수평 속도(&Z): &Vertical Speed: 수직 속도(&V): Wheel Vert. Speed: 휠 수직. 속도: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. 축의 상단에 도달한 후 마우스가 완전히 가속되기 전에 필요한 시간 (초)을 지정합니다. % % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. 추가 가속이 적용되는 시간을 연장합니다. 축 이동이 고려됩니다. 느린 플릭은 추가 가속이 적용되는 실제 시간을 줄입니다. Spring Settings 스프링 설정 Spring Width: 스프링 폭: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. 스프링 모드에서 커서가 이동할 수 있는 영역의 폭을 변경합니다. 0은 화면의 전체 폭을 사용합니다. Spring Height: 스프링 높이: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. 스프링 모드에서 커서가 이동할 수 있는 영역의 높이를 변경합니다. 0은 화면의 전체 높이를 사용합니다. %n notch(es)/s %n 노치/초 QKeyDisplayDialog Key Checker 키 검사기 <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> <html><head/><body><p>이 응용 프로그램에서 키를 감지하는 방법을 보려면 키보드의 키를 누르세요. 창에는 시스템 기본 키 값, Qt에서 제공한 원래 값 (해당되는 경우) 및 AntiMicroX에서 사용하는 사용자 지정 값이 표시됩니다.</p><p>AntiMicroX 키 값과 Qt 키 값은 일반적으로 동일합니다. AntiMicroX는 가능한 경우 Qt에 정의된 키 값을 사용하려고 합니다. Qt에서 정의한 값 목록은 <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> 페이지를 확인하세요. 키가 이 프로그램에서 기본적으로 지원되지 않는 것을 발견하면 AntiMicroX의 <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub 페이지</span></a>에 문제를 보고하여 프로그램이 직접 지원하도록 편집할 수 있도록 하세요. 그대로 사용자 정의 접두사가 알려지지 않은 값에 추가되어 계속 사용할 수 있습니다. 주요 문제는 프로파일이 더 이상 이식 가능하지 않다는 것입니다.</p></body></html> Event Handler: 이벤트 핸들러: Native Key Value: 기본 키 값: 0x00000000 0x00000000 Qt Key Value: Qt 키 값: antimicro Key Value: antimicro 키 값: QObject Super 슈퍼 Menu 메뉴 Mute 음소거 Vol+ 볼륨+ Vol- 볼륨- Play/Pause 재생/정지 Play 재생 Pause 정지 Prev 이전 Next 다음 Mail 메일 Home Media 미디어 Search 검색 Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. 원래 설정(이전에는 %1에 저장됨)이 %2 원하는 경우 원래 디렉토리를 삭제하거나 그대로 둘 수 있습니다. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. 설정 마이그레이션에 문제가 발생했습니다. 원본 구성은 다음 위치에 저장합니다 %1 그러나 그것들의 새 위치는 다음과 같습니다: %2 이전 디렉토리의 이름을 바꾸고 파일의 이름을 antimicrox_settings.ini로 변경하여 수동으로 마이그레이션 할 수 있습니다. Quitting Program 프로그램 종료 중 # of joysticks found: %1 # 발견된 조이스틱 수: %1 List Joysticks: 조이스틱 목록: --------------- --------------- Joystick %1: 조이스틱 %1: Attempting to use fallback option %1 for event generation. 이벤트 생성을 위해 대체 옵션 %1을(를) 사용하려고 합니다. Failed to open event generator. Exiting. 이벤트 생성기를 열지 못했습니다. 종료합니다. Using %1 as the event generator. %1을(를) 이벤트 생성기로 사용합니다. Last button 마지막 버튼 There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? 데이터에 게임패드에서 마지막으로 누른 버튼이 없습니다. 게임 패드에서 키보드용 버튼을 하나 이상 설정했나요? Specified contradicting flags: --show and --hidden 지정된 모순 플래그: --show 및 --hidden Profile location %1 is not an XML file. 프로파일 위치 %1은(는) XML 파일이 아닙니다. Profile location %1 does not exist. 프로파일 위치 %1이(가) 존재하지 않습니다. Controller identifier is not a valid value. 컨트롤러 식별자가 유효한 값이 아닙니다. An invalid set number '%1' was specified. 잘못된 설정 번호 '%1'이(가) 지정되었습니다. Controller identifier '%s'' is not a valid value. 컨트롤러 식별자 '%s''은(는) 유효한 값이 아닙니다. No set number was specified. 설정 번호가 지정되지 않았습니다. An invalid event generator was specified. 잘못된 이벤트 생성기가 지정되었습니다. No event generator string was specified. 이벤트 생성기 문자열이 지정되지 않았습니다. Unknown log level: 알 수 없는 로그 수준: No log file specified. 지정된 로그 파일이 없습니다. xinput version must be at least 2.0. No mouse acceleration changes will occur. xinput 버전은 2.0 이상이어야 합니다. 마우스 가속 변경이 발생하지 않습니다. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: uinput 파일을 열 수 없습니다. 이벤트 생성에 문제가 발생할 수 있습니다. 가능한 해결책을 확인하려면 다음을 방문하세요: QuickSetDialog Quick Set 빠른 설정 <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>버튼을 누르거나 %1 (<span style=" font-weight:600;">%2</span>)에서 축을 이동하세요.<br/>그러면 할당할 수 있는<br/>대화 상자 창이 나타납니다.</p></body></html> Quick Set %1 빠른 설정 %1 SetAxisThrottleDialog Throttle Change 스로틀 변경 The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? 축 %1에 대한 스로틀 설정이 변경되었습니다. 이 스로틀 변경 사항을 모든 설정에 배포하겠습니까? SetJoystick Set %1: %2 설정 %1: %2 Set %1 설정 %1 SetNamesDialog Set Name Settings 설정 이름 설정 Set 1 설정 1 Set 2 설정 2 Set 3 설정 3 Set 4 설정 4 Set 5 설정 5 Set 6 설정 6 Set 7 설정 7 Set 8 설정 8 Name 이름 SimpleKeyGrabberButton Mouse 마우스 SpringModeRegionPreview Spring Mode Preview 스프링 모드 미리보기 UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput 유효한 uinput 장치 파일을 찾을 수 없습니다. uinput 모듈이 불러왔는지 확인하세요. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device uinput 장치 파일을 열 수 없음 장치에 쓰기 권한이 있는지 확인 Using uinput device file %1 uinput 장치 파일 %1 사용 중 UInputHelper a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z Esc Esc F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace BackSpace Tab Tab [ [ ] ] \ \ CapsLock CapsLock ; ; ' ' Enter Enter Shift_L Shift_L , , . . / / Ctrl_L Ctrl_L Super_L Super_L Alt_L Alt_L Space Space Alt_R Alt_R Menu Menu Ctrl_R Ctrl_R Shift_R Shift_R Up Up Left Left Down Down Right Right PrtSc PrtSc Ins Ins Del Del Home Home End End PgUp PgUp PgDn PgDn NumLock NumLock * * + + KP_Enter KP_Enter KP_1 KP_1 KP_2 KP_2 KP_3 KP_3 KP_4 KP_4 KP_5 KP_5 KP_6 KP_6 KP_7 KP_7 KP_8 KP_8 KP_9 KP_9 KP_0 KP_0 SCLK SCLK Pause Pause Super_R Super_R Mute 음소거 VolDn VolDn VolUp VolUp Play 재생 Stop 정지 Prev 이전 Next 다음 [NO KEY] [키 할당 없음] UnixWindowInfoDialog Captured Window Properties 캡처된 창 속성 Information About Window 창에 대한 정보 Class: 등급: TextLabel 텍스트레이블 Title: 제목: Path: 경로: Match By Properties 속성별 일치 Class 등급 Title 제목 Path 경로 VDPad VDPad 가상 십자 패드 VirtualKeyPushButton Space Space Tab Tab Shift (L) Shift (왼쪽) Shift (R) Shift (오른쪽) Ctrl (L) Ctrl (왼쪽) Ctrl (R) Ctrl (오른쪽) Alt (L) Alt (왼쪽) Alt (R) Alt (오른쪽) Alt Gr Alt Gr ` ` ~ ~ - ~ = = [ [ ] ] \ \ Caps Caps ; ; ' ' , , . . / / ESC ESC PRTSC PRTSC SCLK SCLK INS INS PGUP PGUP DEL DEL PGDN PGDN 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK NUM LK * * + + Enter Enter Del Del < < : : Super (L) Super (왼쪽) Menu Menu Up Up Down Down Left Left Right Right VirtualKeyboardMouseWidget Keyboard 키보드 Mouse 마우스 Mouse Settings 마우스 설정 Left Mouse 왼쪽 Up Mouse 위쪽 Left Button Mouse 왼쪽 버튼 Middle Button Mouse 가운데 버튼 Right Button Mouse 오른쪽 버튼 Wheel Up Mouse 휠 위로 Wheel Left Mouse 휠 아래로 Wheel Right Mouse 휠 오른쪽 Wheel Down Mouse 횔 아래로 Down Mouse 아래쪽 Right Mouse 오른쪽 Button 4 Mouse 버튼 4 Mouse 8 Mouse 마우스 8 Button 5 Mouse 버튼 5 Mouse 9 Mouse 마우스 9 NONE 없음 [NO KEY] [키 할당 없음] Last button 마지막 버튼 Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad 게임패드용 키보드에서 설정한 버튼이 없기 때문에 버튼용 슬롯을 지울 수 없습니다. 키보드에서 게임패드로 하나 이상의 버튼 매핑 Others 기타 Applications 응용 프로그램 Browser Back 브라우저 뒤로 가기 Browser Favorites Browser 즐겨찾기 Browser Forward 브라우저 앞으로 가기 Browser Home 브라우저 홈으로 Browser Refresh 브라우저 새로 고침 Browser Search 브라우저 검색 Browser Stop 브라우저 정지 Calc 계산기 Email 이메일 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media 미디어 Media Next 미디어 다음 Media Play 미디어 재생 Media Previous 미디어 이전 Media Stop 미디어 정지 Search 검색 Volume Down 볼륨 낮춤 Volume Mute 볼륨 소거 Volume Up 볼륨 높임 VirtualMousePushButton INVALID 유효하지 않음 WinAppProfileTimerDialog Capture Application 캡처 응용 프로그램 After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. "캡쳐 응용 프로그램" 버튼을 누른 후 프로파일을 연결하려는 응용 프로그램 창을 선택하세요. 선택한 시간 (초) 후에 활성 응용 프로그램이 캡처됩니다. Timer: 타이머: Seconds Cancel 취소 WinExtras [NO KEY] [키 할당 없음] AntiMicro Profile AntiMicro 프로파일 X11Extras ESC ESC Tab Tab Space Space DEL DEL Return Return KP_Enter KP_Enter Backspace Backspace Alt Gr Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput 확장자를 찾을 수 없습니다. 마우스 가속 변경이 발생하지 않습니다. xinput version must be at least 2.0. No mouse acceleration changes will occur. xinput 버전은 2.0 이상이어야 합니다. 마우스 가속 변경이 발생하지 않습니다. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 가상 포인터에 대한 PtrFeedbackClass를 찾을 수 없습니다. id=%1인 장치의 경우 마우스 가속이 변경되지 않음 Changing mouse acceleration for device with id=%1 ID=%1인 장치의 마우스 가속 변경 XMLConfigReader Could not write updated profile XML to file %1. 업데이트된 프로파일 XML을 파일 %1에 쓸 수 없습니다. XMLConfigWriter Could not write to profile at %1. %1의 프로파일에 쓸 수 없습니다. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. 키보드 버튼과 마우스 컨트롤을 게임패드에 매핑하는 데 사용되는 그래픽 프로그램입니다. 게임패드를 지원하지 않는 게임에 유용합니다. main Launch program in system tray only. 시스템 트레이에서만 프로그램을 시작하세요. Launch program with the tray menu disabled 트레이 메뉴가 비활성화된 프로그램 실행 Launch program without the main window displayed 주요 창이 표시되지 않은 상태에서 프로그램 실행 Show app window when hidden. (Used for unhiding window of already running app instance). 숨겨진 경우 앱 창을 표시합니다. (이미 실행 중인 앱 인스턴스의 숨김 해제 창에 사용). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers 선택한 컨트롤러의 기본값으로 선택된 구성 파일로 프로그램을 시작하거나 실행 중인 앱의 활성 프로파일을 변경합니다. 모든 컨트롤러에 대한 기본값 location 위치 Apply configuration file to a specific controller. Value can be a controller index, name, or GUID 특정 컨트롤러에 구성 파일을 적용합니다. 값은 컨트롤러 인덱스, 이름 또는 GUID일 수 있음 value Unload currently enabled profile(s) 현재 활성화된 프로파일 불러오지 않음 value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID 특정 설정에서 조이스틱을 시작합니다. 값은 컨트롤러 인덱스, 이름 또는 GUID일 수 있음 number value 숫자 값 Enable logging. Levels (from the least strict): warn,info,verbose,debug 로깅을 사용하도록 설정합니다. 수준 (가장 덜 엄격한 것부터): 경고, 정보, 자세한 정보, 디버그 log-type 로그 유형 Choose a file for logs writing 로그 작성을 위한 파일 선택 filename 파일이름 Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. 이벤트 생성을 위해 XTest 지원과 uinput 지원 중에서 선택하세요. 리눅스에서 xtest 및 uinput 옵션을 활성화하거나 윈도우즈에서 vmulti를 활성화한 경우에만 사용하세요. 기본값: xtest. event-generation-type 이벤트 생성 유형 Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. SDL에서 감지한 조이스틱에 대한 정보를 인쇄합니다. sdl 라이브러리가 있는 경우에만 사용세요오. 컨트롤러 색인, 이름 또는 GUID를 확인할 수 있습니다. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_nb_NO.ts000066400000000000000000013105631471077622000277630ustar00rootroot00000000000000 AboutDialog About Om Version Versjon Info Info Changelog Endringslogg Credits Bidragsytere AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> dette er en pistol <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> IKKE BRUK DETTE SOM EN ULOVLIG TYRANT About Development Om utviklingen "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. "pktiuk" (siden august 2020) Jeg vil bare sikre at denne svært nyttige programvaren ikke blir forlatt, jeg bestemte meg for å fortsette å gi støtte til dette prosjektet og gjøre det så lett tilgjengelig som mulig. "juliagoda" (siden mars 2018 til 2020) Jeg ønsket bare å spille mine favorittspill som ikke støtter gamepads, og fant dette prosjektet (som kartlegger tastaturtaster og museknapper til tilkoblede gamepads på Linux) som mest riktig og nylig. Men på grunn av dårlige valg av en slik applikasjon på internett og siden den ikke kompilerte riktig, bestemte jeg meg for å redde prosjektet. Men når jeg var ferdig med arbeidet (nok til å like å spille spill) tenkte jeg å dele denne koden med andre. Selvfølgelig vil all informasjon om tidligere programmerere bli holdt. "Ryochan7" (siden 30. desember 2012 til 2017) har jeg jobbet med AntiMicro på fritiden. Det som opprinnelig startet som en gaffel av QJoyPad og en måte å lære skikkelig hendelsesdrevet programmering på, har blitt til noe mye større enn jeg opprinnelig hadde tenkt. Selv om jeg har brukt mye tid på å lære nye teknikker, finne ut mer om domenet til KB+M-emulering og tilbringe fredagskvelder med å slå hodet mot tastaturet, har det totalt sett vært en morsom og berikende opplevelse. Behovet for dette programmet kom fra at jeg brukte lignende programmer på Windows for å spille flere spill som ikke ga innebygd kontrollerstøtte. Selv om det fantes noen alternativer på Linux, var det egentlig ikke noe jeg følte var godt nok med tanke på funksjonalitet eller kontroller i spillet for å virkelig nyte spill jeg ønsket å spille med ved hjelp av KB+M-emulering. QJoyPad var hovedprogrammet jeg hadde brukt tidligere, selv om det hadde blitt mye eldre og det ikke ga noen grunnleggende funksjonalitet som jeg trodde var avgjørende. Prosjektet var dødt da det ikke hadde blitt oppdatert på flere år, så jeg bestemte meg for å lage mitt eget. Siden den gang har jeg prøvd å finne ut hva de andre programmene gjør riktig og deretter forbedre det. Jeg har også oppdaget noen fine triks underveis, og jeg har lært mer om hvordan native gamepad-kontroller er implementert i noen spill enn jeg noen gang egentlig ønsket å vite. Selv om det definitivt er områder hvor dette programmet kan forbedres, finner jeg ut at dette programmet tilbyr den beste kontrollopplevelsen i spillet for å spille eldre, og noen nyere, spill som ikke gir støtte for innebygd kontroller. Utvikling av dette programmet er ikke like høyt prioritert for meg lenger. Dette skyldes hovedsakelig at Steam-kontrolleren fungerer ganske bra for oppgaven med å spille PC-spill sammenlignet med å bruke en Xbox 360-kontroller. Det ser imidlertid ut til at det fortsatt er en grunn til at dette programmet skal eksistere en stund. --- Fra og med 24. mai 2016 har dette prosjektet flyttet til https://github.com/AntiMicro/ Copyright: 2013 - 2022 Opphavsrett: 2013–2023 License Lisens Program Version %1 Programversjon %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Kompilert %1 klokken 52 Built Against SDL %1 Bygd med SDL %1 Running With SDL %1 Kjører med SDL %1 Using Qt %1 Bruker Qt %1 Using Event Handler: %1 Bruker begivenhetshåndterer: %1 AddEditAutoProfileDialog Auto Profile Dialog Dialog om automatisk profil Pro&file: Pro&fil: Browse Utforsk Window: Vindu: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Velg Vindu. Klikk på den aktuelle applikasjonen vinduet og programfilbanen vil bli fylt ut i skjemaet. Detect Window Properties Finn vinduets egenskaper &Class: &Klasse: T&itle: Tittel: set partial title angi deltittel Application: Applikasjon: Select Velg De&vices: En&heter: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Velg denne profilen som standard lastet for den angitte enheten. Utvalget vil bli brukt i stedet av alle standardprofilalternativet. Set as Default for Controller Sett som standard for kontroller A different profile is already selected as the default for this device. En annen profil er allerede valgt som standard for denne enheten. Current (%1) Gjeldende (%1) Open Config Åpne Config Select Program Velg Program Programs (*.exe) Programmer (*.exe) Please use the main default profile selection. Vennligst bruk hovedstandardprofilvalget. Main Profile Hovedprofil Already selected Allerede valgt Chosen Profile Valgt profil The selection will be used instead of the all default profile option. Utvalget vil bli brukt i stedet av alle standardprofilalternativet. Please select a window by using the mouse. Press Escape if you want to cancel. Capture Application Window Could not obtain information for the selected window. Application Capture Failed Profile file path is invalid. No window matching property was specified. Program path is invalid or not executable. File is not an .exe file. No window matching property was selected. AdvanceButtonDialog Advanced Avansert Assignments Toggle Turbo Set Selector Blank or KB/M Hold Pause Cycle Distance Avstand Insert Sett inn Delete Slett Clear All Tøm alle Time: Tid: 0.01s 0,01 s 0s 0 s Insert a pause that occurs in between key presses. Release Utgave Insert a new blank slot. Delete a slot. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. 0m 0 m &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: Avstand: % % Mouse Mod Press Time Delay Forsinkelse Execute Kjør Load Last inn Set Change Text Entry Join Bind sammen Split Del opp Placeholder Plassholder 0 0 Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After seconds sekunder Executable: Kjørbar fil: ... Arguments: Argumenter: Enabled Mode: Modus: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Delay: Forsinkelse: 0.10s 0,10 s Rate: 10.0/s Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] [NO KEY] sec. /sec. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist Filen finnes ikke There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: X-akse: Y Axis: Y-akse: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Opp: Down: Ned: Left: Venstre: Right: Høyre: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Akser Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Ingen Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Haptic Trigger: Name: Navn: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Forhåndsinnstillinger: Dead Zone: Max Zone: [NO KEY] [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Plassholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Last keyboard/mouse button: Slots Na&me: Na&vn: Specify the name of a button. Action: Handling: Specify the action that will be performed in game while this button is being used. Advanced Avansert Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Skjema Input to calibrate: Steps Z TextLabel X X gain offset Y Y Start calibration Close Reset settings Save Lagre Calibration Kalibrering Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: Klasse: TextLabel Title: Path: Sti: Match By Properties Class Klasse Title Path Sti Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Piltaster Keys: W | A | S | D NumPad None Ingen Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Forhåndsinnstillinger: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Piltaster Keys: W | A | S | D NumPad None Ingen Dpad Mode: &Name: &Navn: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Profil: Browse Utforsk Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A A B B X X Y Y Back Tilbake Start Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Tilbake Guide Start Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAccelerometerButton Up Opp Down Ned Left Venstre Right Høyre Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis Akse JoyAxisButton Negative Negativ Positive Positiv Unknown Ukjent Button Knapp JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Ingen Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button Knapp [NO KEY] [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Tøm Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Mus Up Opp Down Ned Left Venstre Right Høyre LB MB RB Pause Hold Cycle Distance Avstand Release Utgave Mouse Mod Press Time Delay Forsinkelse Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] [NO KEY] JoyControlStick Stick JoyControlStickButton Up Opp Down Ned Left Venstre Right Høyre Button Knapp JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Piltaster Keys: W | A | S | D NumPad None Ingen Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: X: 0 0 Y: Y: Distance: Avstand: Presets: Forhåndsinnstillinger: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Piltaster Keys: W | A | S | D NumPad None Ingen Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % % Stick Delay: Time lapsed before a direction change is taken into effect. s s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Na&vn: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Opp Down Ned Left Venstre Right Høyre Button Knapp JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Knapp JoySensorContextMenu Mouse Settings JoySensorEditDialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: Presets: Forhåndsinnstillinger: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. s s Na&me: Na&vn: Specify the name of an analog sensor. Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set %1 JoySensorPreset None Ingen Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Piltaster Keys: W | A | S | D NumPad JoyTabWidget <New> <Ny> Battery level of controller Remove Fjern Remove configuration from recent list. Load Last inn Load configuration file. Save Lagre Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Innstillinger Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Navn Toggle button name displaying. Pref Change global profile settings. Reset Tilbakestill Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sensors DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Egenskaper Details Detaljer Name: Navn: %1 %1 Number: Nummer: Axes: Akser: Buttons: Knapper: Hats: Sensors: Battery: Batteri: Unknown Ukjent GUID: GUID: Game Controller: Axes Akser Buttons Knapper Hats Sensors %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None Ingen Axis %1 Hat %1 No Nei Yes Ja MainSettingsDialog Edit Settings General Generelt Controller Mappings Language Språk Auto Profile Mouse Mus Advanced Avansert <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Fransk Deutsch Tysk Italiano Italiensk 日本語 Русский Russisk српски / srpski 简体中文 Español Spansk українська Ukrainsk Polski Polsk History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Ingen Error Feil Warning Advarsel Info Info Verbose Debug Avlusing Note: To see the change of log level in console output (not in log file), application restart is required Reset Tilbakestill Class Klasse Pro&file Directory: Show low battery notification Show empty battery notification Title Program Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Utmykning Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Skjerm: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: Forsinkelse: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID GUID Mapping String Disable? Delete Slett Default Forvalg English Engelsk Active Aktiv Devices: Enheter: All Alle Device Enhet Profile Profil Default? Forvalg? Add Legg til Edit Rediger AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Program &Options He&lp Hj&elp &Quit &Avslutt Ctrl+Q Ctrl+Q &Update Joysticks Ctrl+U Ctrl+U &Hide &Skjul Ctrl+H Ctrl+H &About &Om Ctrl+A Ctrl+A About &Qt Ctrl+T Ctrl+T &Properties &Egenskaper Ctrl+P Ctrl+P &Key Checker Ctrl+K Ctrl+K &GitHub Page Ctrl+G Ctrl+G S&ettings I&nnstillinger Ctrl+S Ctrl+S &Stick/Pad Assign Ctrl+X Ctrl+X &Wiki &Wiki Ctrl+W Ctrl+W &Issues &Problemer Ctrl+I &Calibration &Kalibrering Ctrl+C Home Page (%1) (%1) Open File Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore &Gjenopprett Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Failed to elevate program Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSensorSettingsDialog Mouse Settings Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Lineær Quadratic Kvadratisk Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: &Multiplikator: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: Sensitivite&t: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s s Highest value to accelerate mouse movement by x x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: X: 0 (0 pps) Y: Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Forstum Vol+ Vol- Play/Pause Play Pause Prev Next Neste Mail Home Media Search Søk Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name Navn SimpleKeyGrabberButton Mouse Mus SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a a b b c c d d e f g h i j k l m n o p q r s s t u v w x x y y z z Esc Esc F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Opp Left Venstre Down Ned Right Høyre PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute Forstum VolDn VolUp Play Stop Prev Next Neste [NO KEY] [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: Klasse: TextLabel Title: Path: Sti: Match By Properties Class Klasse Title Path Sti VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK * + Enter Del < : Super (L) Menu Up Opp Down Ned Left Venstre Right Høyre VirtualKeyboardMouseWidget Keyboard Mouse Mus Mouse Settings Left Mouse Venstre Up Mouse Opp Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Ned Right Mouse Høyre Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media Media Next Media Play Media Previous Media Stop Search Søk Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel Avbryt WinExtras [NO KEY] [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program in system tray only. Launch program with the tray menu disabled Launch program with the tray menu disabled Launch program without the main window displayed Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value value Unload currently enabled profile(s) Unload currently enabled profile(s) value(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID Start joysticks on a specific set. Value can be a controller index, name, or GUID number value number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type log-type Choose a file for logs writing Choose a file for logs writing filename filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_nl.ts000066400000000000000000013057321471077622000274030ustar00rootroot00000000000000 AboutDialog About Version Info Changelog Veranderingslog Credits Credits AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development Over ontwikkeling "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Copyright: 2013 - 2022 License licentie Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 AddEditAutoProfileDialog Auto Profile Dialog Pro&file: Browse Window: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Detect Window Properties &Class: T&itle: set partial title Application: Select De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Set as Default for Controller A different profile is already selected as the default for this device. Current (%1) Open Config Select Program Programs (*.exe) Please use the main default profile selection. Main Profile Already selected Chosen Profile The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. Capture Application Window Could not obtain information for the selected window. Application Capture Failed Profile file path is invalid. No window matching property was specified. Program path is invalid or not executable. File is not an .exe file. No window matching property was selected. AdvanceButtonDialog Advanced Assignments Toggle Turbo Set Selector Blank or KB/M Hold Pause Cycle Distance Insert Delete Clear All Time: 0.01s 0s Insert a pause that occurs in between key presses. Release Insert a new blank slot. Delete a slot. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. 0m &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: % Mouse Mod Press Time Delay Execute Load Set Change Text Entry Join Split Placeholder 0 Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After seconds Executable: ... Arguments: Enabled Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Delay: 0.10s Rate: 10.0/s Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] sec. /sec. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: Y Axis: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Down: Left: Right: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Haptic Trigger: Name: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Dead Zone: Max Zone: [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Attach the numeric keypad Last keyboard/mouse button: Slots Na&me: Specify the name of a button. Action: Specify the action that will be performed in game while this button is being used. Advanced Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel TextLabel X X gain offset Y Y Start calibration Close Reset settings Save Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAccelerometerButton Up Up Down Down Left Left Right Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Negative Positive Unknown Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Up Down Left Right LB MB RB Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] JoyControlStick Stick JoyControlStickButton Up Down Left Right Button JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: 0 Y: Distance: Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Down Left Right Button JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Button JoySensorContextMenu Mouse Settings Mouse Settings JoySensorEditDialog Dialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Safe Zone: Presets: Presets: Dead Zone: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: Diagonal Range: The area (in degrees) that each diagonal region occupies. The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Na&me: Na&me: Specify the name of an analog sensor. Mouse Settings Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None None Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad JoyTabWidget <New> Battery level of controller Remove Remove configuration from recent list. Load Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sensors DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Details Name: %1 Number: Axes: Buttons: Hats: Sensors: Battery: Unknown GUID: Game Controller: Axes Buttons Hats Sensors %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None None Axis %1 Hat %1 No Yes MainSettingsDialog Edit Settings General Controller Mappings Language Auto Profile Mouse Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Pro&file Directory: Show low battery notification Show empty battery notification Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID Mapping String Disable? Delete Default English Active Devices: All Device Profile Default? Add Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Options He&lp &Quit Ctrl+Q &Update Joysticks Ctrl+U &Hide Ctrl+H &About Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page (%1) Open File Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Failed to elevate program Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSensorSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Prev Next Mail Home Media Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name SimpleKeyGrabberButton Mouse SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 2 3 4 5 6 7 8 9 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK * + Enter Del < : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard Mouse Mouse Settings Left Mouse Up Mouse Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel WinExtras [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_pl.ts000066400000000000000000013372111471077622000274020ustar00rootroot00000000000000 AboutDialog About O programie AntiMicroX AntiMicroX Version Wersja Credits Przypisy <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Prawa autorskie: 2013 - 2022 Info Info License Licencja Changelog Dziennik zmian About Development O rozwoju Program Version %1 Wersja programu %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Program skompilowany na %1 z pomocą %2 Built Against SDL %1 Zbudowane z biblioteką SDL %1 Running With SDL %1 Uruchomione z biblioteką SDL %1 Using Qt %1 Z użyciem Qt %1 Using Event Handler: %1 Z użyciem procedury obsługi zdarzenia: %1 AddEditAutoProfileDialog Auto Profile Dialog Okno Autoprofilu Pro&file: Pro&fil: Browse Przeglądaj Window: Okno: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Zaznacz okno. Kliknij na odpowiednie okno aplikacji, a ścieżka aplikacji zostanie automatycznie dodana do rubryki. Detect Window Properties Wykryj właściwości okna &Class: &Klasa: T&itle: T&ytuł: set partial title ustaw częściowy tytuł Application: Aplikacja: Select Zaznacz De&vices: Urz&ądzenia: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Zaznacz ten profil, by go domyślnie załadować dla określonego urządzenia. Wybór zostanie użyty zamiast domyślnej opcji. Set as Default for Controller Ustaw jako domyślny dla kontrolera A different profile is already selected as the default for this device. Inny profil jest aktualnie zaznaczony jako domyślny dla tego urządzenia. Current (%1) Aktualny (%1) Open Config Otwórz konfigurację Select Program Zaznacz program Programs (*.exe) Programy (*.exe) Please use the main default profile selection. Zaleca się użycie wyboru głównego domyślnego profilu. Main Profile Główny profil Already selected Już zaznaczono Chosen Profile Wybrany profil The selection will be used instead of the all default profile option. Wybór zostanie użyty zamiast wszystkich opcje profilu domyślnego. Please select a window by using the mouse. Press Escape if you want to cancel. Zaznacz okno za pomocą myszki. Wciśnij Escape, jeśli chcesz anulować. Capture Application Window Przechwyć okno aplikacji Could not obtain information for the selected window. Nie można uzyskać informacji dla zaznaczonego okna. Application Capture Failed Przechwytywanie okna zostało zakończone niepowodzeniem Profile file path is invalid. Ścieżka profilu jest nieprawidłowa. No window matching property was specified. Nie została określona żadna pasująca właściwość dla okna. Program path is invalid or not executable. Ścieżka programu jest nieprawidłowa lub nie jest wykonywalna. File is not an .exe file. Plik nie jest plikiem .exe. No window matching property was selected. Nie została zaznaczona żadna pasująca właściwość dla okna. AdvanceButtonDialog Advanced Zaawansowane Assignments Przypisania Toggle Przycisk przełączania Turbo Przycisk turbo Set Selector Wybierz selektor Blank or KB/M Pusty lub KB/M Cycle Cykl Delay Opóźnienie Distance Odległość Execute Wywołanie Hold Przytrzymanie Load Załadowanie Mouse Mod Moduł myszki Pause Przerwa Press Time Przytrzymanie okresowo Release Zwolnienie Set Change Zmiana ustawienia Text Entry Wprowadzenie tekstu Insert a new blank slot. Dodaj nowy pusty slot. Insert Dodaj Join Połącz Split Podziel Delete a slot. Usuń slot. Delete Usuń Clear all currently assigned slots. Wyczyść wszystkie aktualnie przypisane sloty. Clear All Wyczyść wszystko Placeholder Zastępstwo Specify the duration of an inserted Pause or Hold slot. Określ czas trwania wprowadzonego slotu "Przerwa" lub "Przytrzymanie". Time: Czas: 0.01s 0.01s 0m 0m 0 0 0s 0s &Mouse Speed Mod: &Moduł prędkości myszki: Set the percentage that mouse speeds will be modified by. Ustaw wartość w procentach, o którą prędkość myszki zostanie zmieniona. % % Specify the range past an axis dead zone in which a sequence of actions will execute. Określ przedział martwej strefy dla osi, w którym zostanie wywołana kolejność akcji. Distance: Odległość: Auto Reset Cycle After Automatycznie resetuj cykl po seconds sekundach Choose Profile Wybierz profil Executable: Wykonywalny: ... ... Arguments: Argumenty: Enabled Odblokowane Mode: Tryb: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>Standardowo: Cyklicznie jest wciskany i zwalniany przycisk według wybranej prędkości.</p><p>Gradientowo: Zmienia opóźnienie wciśnięcia przycisku i jego zwolnienie według odległości pokonanej przez oś. Częstotliwość pozostaje niezmieniona.</p><p>Pulsowo: Zmienia częstotliwość naciskania i zwalniania przycisku na sekundę. Opoźnienie przycisku pozostaje niezmienione.</p></body></html> Normal Standardowo Gradient Gradientowo Pulse Pulsowo Delay: Opoźnienie: 0.10s 0.10s Rate: Tempo: 10.0/s 10.0/s Disabled Zablokowany Select Set 1 One Way Zaznacz zestawienie 1 jednokierunkowe Select Set 1 Two Way Zaznacz zestawienie 1 dwukierunkowe Select Set 1 While Held Zaznacz zestawienie 1 podczas trzymania Select Set 2 One Way Zaznacz zestawienie 2 jednokierunkowe Select Set 2 Two Way Zaznacz zestawienie 2 dwukierunkowe Select Set 2 While Held Zaznacz zestawienie 2 podczas trzymania Select Set 3 One Way Zaznacz zestawienie 3 jednokierunkowe Select Set 3 Two Way Zaznacz zestawienie 3 dwukierunkowe Select Set 3 While Held Zaznacz zestawienie 3 podczas trzymania Select Set 4 One Way Zaznacz zestawienie 4 jednokierunkowe Select Set 4 Two Way Zaznacz zestawienie 4 dwukierunkowe Select Set 4 While Held Zaznacz zestawienie 4 podczas trzymania Select Set 5 One Way Zaznacz zestawienie 5 jednokierunkowe Select Set 5 Two Way Zaznacz zestawienie 5 dwukierunkowe Select Set 5 While Held Zaznacz zestawienie 5 podczas trzymania Select Set 6 One Way Zaznacz zestawienie 6 jednokierunkowe Select Set 6 Two Way Zaznacz zestawienie 6 dwukierunkowe Select Set 6 While Held Zaznacz zestawienie 6 podczas trzymania Select Set 7 One Way Zaznacz zestawienie 6 jednokierunkowe Select Set 7 Two Way Zaznacz zestawienie 7 dwukierunkowe Select Set 7 While Held Zaznacz zestawienie 7 podczas trzymania Select Set 8 One Way Zaznacz zestawienie 8 jednokierunkowe Select Set 8 Two Way Zaznacz zestawienie 8 dwukierunkowe Select Set 8 While Held Zaznacz zestawienie 8 podczas trzymania [NO KEY] [BRAK] sec. sek. /sec. /sek. Not checked slots Niesprawdzone sloty To delete slots, you need to select at least one Aby usunąć sloty, należy wybrać co najmniej jeden z nich To insert slots, you need to select at least one Aby wstawić sloty, należy wybrać co najmniej jeden z nich Unknown current slot Nieznany aktualny slot Click on chosen slots before joining them Kliknij na wybrane sloty przed ich połączeniem Not enough slots Za mało slotów It's impossible to join slots. Add at least one other slot. Niemożliwe jest dołączenie do slotów. Dodaj co najmniej jeden inny slot. Not selected slots Niewybrane sloty It's impossible to join slots. Select at least two slots before joining them Niemożliwe jest dołączenie do slotów. Wybierz co najmniej dwa sloty przed ich połączeniem Only keyboard slots Tylko sloty klawiatury It's only possible to join simple and mix keyboard slots Możliwe jest tylko łączenie prostych slotów oraz slotów mieszanych (minislotów) It's impossible to split slots. Add at least one other slot. Nie da się rozdzielić slotów. Dodaj co najmniej jeden inny slot. Not selected slot Niewybrany slot Select your slot before splitting. Wybierz swój slot przed próbą podzielenia. Too many mix slots Zbyt wiele łączonych slotów Select one mix slot. Wybierz jeden łączony slot. Only mix slots Tylko łączone sloty It's only possible to split mix slot. Możliwe jest tylko dzielenie łączonych slotów (minislotów). Empty execution path Pusta ścieżka wykonania Line for execution file path is empty. Fill the first line before you are going to add a slot. Linia odpowiadająca za scieżkę do pliku wykonywalnego jest pusta. Uzupełnij rubrykę zanim dodasz slot. File doesn't exist Plik nie istnieje There is no such file locally, that could be executed. Check the file on your system Takiego pliku nie odnaleziono w podanej ścieżce. Sprawdź, czy pod tą ścieżką znajduje się taki plik Set %1 Zestawienie %1 Select Set %1 Wybierz zestawienie %1 One Way Jednokierunkowo Two Way Dwukierunkowo While Held Podczas trzymania Config Files (*.amgp *.xml) Pliki konfiguracyjne (*.amgp *.xml) Choose Executable Wybierz plik wykonywalny Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Sloty za cyklem zostaną wywołane przy kolejnym naciśnięciu przycisku. Wielokrotne cykle mogą być dodane w kolejności, by tworzyć podziały w sekwencji. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Opóźnia czas trwania wywołania następnego slotu według określonego czasu. Sloty aktywowane przed wystąpieniem opóźnienia pozostaną aktywne po przeminięciu określonego czasu dla opóźnienia. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Akcja odległości określa wywoływanie slotów, gdy oś jest przesuwana w określonym przedziale za wyznaczoną martwą strefą. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Wprowadź akcję przytrzymania. Sloty po tej akcji zostaną wywołane, jeśli przycisk ten został trzymany przez określoną umowną ilość czasu. Chose a profile to load when this slot is activated. Wybierz profil do załadowywania gdy slot jest aktywny. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Akcja modułu myszki zmieni wszystkie ustawienia prędkości myszki według określonej liczby procentowej, podczas gdy wykonywana jest akcja. Opcja ta moze być użyteczna dla zwolnienia prędkosci myszki podczas strzelania. Insert a pause that occurs in between key presses. Dodaj przerwę, która występuje pomiędzy naciskanymi klawiszami. Specify the time that keys past this slot should be held down. Określ czas, przez który klawisze z tego slotu powinny być przytrzymywane. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Wprowadź akcję zwalniania. Sloty po tej akcji zostaną wywołane po zwolnieniu przycisku, jeśli przycisk ten został trzymany przez określoną umowną ilość czasu. Change to selected set once slot is activated. Zmień zaznaczone zestawienie gdy slot jest aktywowany. Full string will be typed when a slot is activated. Pełna treść zostania wpisana gdy slot zostanie aktywowany. Execute program when slot is activated. Wykonaj program gdy slot jest aktywny. AdvanceStickAssignmentDialog Stick/Pad Assignment Przypisanie do Joysticka/Gamepada Sticks Joysticki DPads Pady kierunkowe Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. Uwaga: To okno jest przeznaczone do kompatybilności wstecznej z profilami przed Antimicro 2.0. Od wersji 2.0 preferowane jest korzystanie z okna mapowania kontrolera gry. %1 (Joystick %2) %1 (Joystick %2) Stick 1 Joystick 1 Enabled Odblokowany Assign Przypisz X Axis: Oś X: Y Axis: Oś Y: Stick 2 Joystick 2 Number of Physical DPads: %1 Liczba fizycznych padów kierunkowych: %1 Virtual DPad 1 Wirtualny pad kierunkowy 1 Down: Dół: Left: Lewo: Right: Prawo: Up: Góra: Axis %1 Oś %1 Axis %1 - Oś %1 - Axis %1 + Oś %1 + Button %1 Przycisk %1 Move stick 1 along the X axis Porusz gałką 1 wzdłuż osi X Move stick 1 along the Y axis Porusz gałką 1 wzdłuż osi Y Move stick 2 along the X axis Porusz gałką 2 wzdłuż osi X Move stick 2 along the Y axis Porusz gałką 2 wzdłuż osi Y Press a button or move an axis Wciśnij przycisk lub porusz gałką wzdłuż osi AxisEditDialog Axis Presets: Predefinicje: Mouse (Horizontal) Mysz (poziomo) Mouse (Inverted Horizontal) Mysz (w odwróconym poziomie) Mouse (Vertical) Mysz (pionowo) Mouse (Inverted Vertical) Mysz (w odwróconym pionie) Arrows: Up | Down Strzałki: Góra | Dół Arrows: Left | Right Strzałki: Lewo | Prawo Keys: W | S Klawisze: W | S Keys: A | D Klawisze: A | D NumPad: KP_8 | KP_2 Klawisze num: KP_8 | KP_2 NumPad: KP_4 | KP_6 Klawisze num: KP_4 | KP_6 None Brak Set the value to use as the limit for an axis. Useful for a worn out analog stick. Ustaw wartość limitu dla osi. Opcja jest przydatna dla zużytej gałki analogowej. Dead Zone: Martwa strefa: Set the value of the dead zone for an axis. Ustaw wartość martwej strefy dla osi. Max Zone: Maksymalna strefa: [NO KEY] [BRAK] Throttle setting that determines the behavior of how to interpret an axis hold or release. Ustawienia przepustnicy, które determinują zachowanie sposobu interpretacji trzymania osi i jej zwalniania. Negative Half Throttle Ujemny zakres ruchu osi do połowy Negative Throttle Ujemny zakres ruchu osi Normal Standardowy Positive Throttle Dodatni zakres ruchu osi Positive Half Throttle Dodatni zakres ruchu osi do połowy Haptic Trigger: Current Value: Aktualna wartość: Name: Nazwa: Specify the name of an axis. Określ nazwę osi. Mouse Settings Ustawienia myszki Set Ustaw Set %1 Zestawienie %1 Left Mouse Button Lewy przycisk myszy Right Mouse Button Prawy przycisk myszy Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog Okno dialogowe To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Wciśnij dowolny klawisz lub kliknij na przycisk myszy, by stworzyć nowe przypisanie Placeholder Zastępstwo Enables a key press or release to only occur when a controller button is pressed. Odblokowuje naciśnięcie klawisza lub zwolnienie go, gdy przycisk kontrolera jest wciśnięty. Toggle Przycisk przełączania Enables rapid key presses and releases. Turbo controller. Odblokowuje szybsze naciskanie klawiszy i ch zwalnianie. Kontroler turbo. Turbo Przycisk turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Pamiętaj, że nie będzie działać, jeśli nie masz takiej klawiatury podłączonej do komputera lub jeśli nie jest ona wbudowana jak w komputerach stacjonarnych Attach the numeric keypad Podłącz klawiaturę numeryczną Last keyboard/mouse button: Ostatni przycisk klawiatury/myszy: Slots Sloty Na&me: Naz&wa: Specify the name of a button. Określ nazwę przycisku. Action: Akcja: Specify the action that will be performed in game while this button is being used. Określ akcję, która będzie się wykonywała w grze, podczas gdy przycisk jest wciśnięty. Advanced Zaawansowany Choose your keyboard key Naciśnij dowolny klawisz No button Brak przycisku Last button Ostatni przycisk To change settings for last button, it must be at least one assignment from keyboard to gamepad Musi istnieć co najmniej jedno przypisanie z klawiatury do gamepad'a, by zmienić ustawienia dla ostatniego przycisku To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad Musi istnieć co najmniej jedno przypisanie z klawiatury do gamepad'a, by zmienić ustawienia turbo dla ostatniego przycisku No choice Brak wyboru Before you open window with advanced settings, you have to choice a key Zanim otworzysz okno z zaawansowanymi ustawieniami, musisz wybrać klawisz To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Potrzebne jest co najmniej jedno mapowanie z klawiatury do gamepad'a, by móc otworzyć okno z zaawansowanymi ustawieniami Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Sloty dla wprowadzonych przycisków nie mogły zostać usunięte, ponieważ żadne dane nie zostały dotychczas wprowadzone z układu klawiatury do układu gamepad'a. Stwórz mapowanie co najmniej jednego przycisku dla gamepad'a As last gamepad button has been set Został ustawiony ostatni przycisk gamepad'a Index %1 Indeks %1 Calibration Form Okno Input to calibrate: Steps Z TextLabel Etykieta X X gain offset Y Y Start calibration Rozpocznij kalibrację Close Reset settings Resetuj ustawienia Save Zapisz Calibration Kalibracja Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? Wartości kalibracji były zapisywane dla przycisku. Czy aby napewno zresetować ustawienia? CapturedWindowInfoDialog Captured Window Properties Uchwycone właściwości okna Information About Window Informacje o oknie Class: Klasa: TextLabel Etykieta Title: Tytuł: Path: Ścieżka: Match By Properties Dopasowanie według właściwości Class Klasa Title Tytuł Path Ścieżka Full Path Pełna ścieżka File Name Nazwa pliku DPadContextMenu Mouse (Normal) Mysz (standardowo) Mouse (Inverted Horizontal) Mysz (w odwróconym poziomie) Mouse (Inverted Vertical) Mysz (w odwróconym pionie) Mouse (Inverted Horizontal + Vertical) Mysz (w odwróconym poziomie + pionie) Arrows Strzałki Keys: W | A | S | D Klawisze: W | A | S | D NumPad Klawisze numeryczne None Brak Standard Standard Eight Way Ośmioosiowo 4 Way Cardinal w 4 głównych kierunkach 4 Way Diagonal w 4 głównych przekątnych Mouse Settings Ustawienia myszki DPadEditDialog Dialog Okno dialogowe Presets: Predefinicje: Mouse (Normal) Mysz (standardowo) Mouse (Inverted Horizontal) Mysz (w odwróconym poziomie) Mouse (Inverted Vertical) Mysz (w odwróconym pionie) Mouse (Inverted Horizontal + Vertical) Mysz (w odwróconym poziomie + pionie) Arrows Strzałki Keys: W | A | S | D Klawisze: W | A | S | D NumPad Klawiatura numeryczna None Brak Dpad Mode: Tryb pada kierunkowego: Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Standardowo: Ośmiokierunkowy analog z dwoma aktywnymi przyciskami nakierowującymi, gdy analog jest zwrócony w kierunku ukośnym. Ośmioosiowo: Ośmiokierunkowy analog z ośmioma przyciskami. Tylko jeden przycisk jest aktywny w tym samym czasie. Opcja jest przydatna w przypadku gier podobnych do Rogue. W 4 głównych kierunkach: Czterokierunkowy analog z kierunkami odwołującymi się do głównych kierunków świata. Opcja jest przydatna w przypadku menu W 4 głównych przekątnych: Czterokierunkowy analog z kierunkami odwołującymi się do stref przekątnych analogu. Standard Standardowo Eight Way Ośmioosiowo 4 Way Cardinal W 4 głównych kierunkach 4 Way Diagonal W 4 głównych przekątnych DPad Delay: Opóźnienie pada kierunkowego: Time lapsed before a direction change is taken into effect. Czas, który upłynął przed wykryciem zmiany kierunku. s s &Name: &Nazwa: Specify the name of a dpad. Określ nazwę pada kierunkowego. Mouse Settings Ustawienia myszki Set Ustaw Set %1 Zestawienie %1 EditAllDefaultAutoProfileDialog Default Profile Domyślny profil Profile: Profil: Browse Przeglądaj Open Config Otwórz konfigurację Profile file path is invalid. Ścieżka dla plik jest nieprawidłowa. ExtraProfileSettingsDialog Extra Profile Settings Dodatkowe ustawienia profilu Key Press Time: Czas wciśniętego klawisza: 0.00 ms 0.00 ms Profile Name: Nazwa profilu: s s GameController Game Controller Kontroler GameControllerDPad DPad Pad kierunkowy GameControllerMappingDialog Game Controller Mapping Mapowanie kontrolera <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A A B B X X Y Y Back Powrót Start Start Guide Guide Left Shoulder Right Shoulder Right Shoulder Left Stick Click Wciśnięcie lewego drążka Right Stick Click Wciśnięcie prawego drążka Left Stick X Left Stick Y Right Stick X Right Stick X Right Stick Y Right Stick Y Left Trigger Left Trigger Right Trigger Right Trigger DPad Up DPad Up DPad Left DPad Left DPad Down DPad Down DPad Right DPad Right Mapping Mapowanie SDL 2 Game Controller Mapping String Treść mapowania kontrolera według SDL 2 Last Axis Event: Ostatnie zdarzenie dla osi: Current Axis Detection Dead Zone: Aktualna martwa strefa podczas wykrywania ruchu osią: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Mapowanie kontrolera (%1) (#%2) Discard Controller Mapping? Usunąć mapowanie kontrolera? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. Usunąć mapowanie dla tego kontrolera? Jeśli zostanie usunięte, kontroler zostanie przywrócony do joysticka, gdy tylko zaktualizujesz wszystkie joysticki. GameControllerSet Back Back Guide Guide Start Start LS Click LS Click RS Click RS Click L Shoulder L Shoulder R Shoulder R Shoulder L Trigger L Trigger R Trigger R Trigger GameControllerTrigger Trigger Przyciski Trigger JoyAccelerometerButton Up Góra Down Dół Left Lewo Right Prawo Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Button Przycisk Negative Ujemny Positive Dodatni Unknown Nieznany JoyAxisContextMenu Mouse (Horizontal) Mysz (poziomo) Mouse (Inverted Horizontal) Mysz (w odwróconym poziomie) Mouse (Vertical) Mysz (pionowo) Mouse (Inverted Vertical) Mysz (w odwróconym pionie) Arrows: Up | Down Strzałki: Góra | Dół Arrows: Left | Right Strzałki: Lewo | Prawo Keys: W | S Klawisze: W | S Keys: A | D Klawisze: A | D NumPad: KP_8 | KP_2 Klawiatura num: KP_8 | KP_2 NumPad: KP_4 | KP_6 Klawiatura num: KP_4 | KP_6 None Brak Mouse Settings Ustawienia myszki Left Mouse Button Lewy przycisk myszy Right Mouse Button Prawy przycisk myszy JoyButton Processing turbo for #%1 - %2 Przetwarzanie trybu turbo dla #%1 - %2 Finishing turbo for button #%1 - %2 Finalizacja trybu turbo dla przycisku #%1 - %2 Distance change for button #%1 - %2 Zmiana odległości dla przycisku #%1 - %2 Button Przycisk [NO KEY] [BRAK] [Set %1 1W] [Zestawienie %1 1W] [Set %1 2W] [Zestawienie %1 2W] [Set %1 WH] [Zestawienie %1 WH] JoyButtonContextMenu Toggle Przycisk przełączania Turbo Przycisk turbo Clear Wyczyść Set Select Wybór ustawienia Disabled Zablokowane Set %1 Zestawienie %1 Set %1 1W Zestawienie %1 1W Set %1 2W Zestawienie %1 2W Set %1 WH Zestawienie %1 WH JoyButtonSlot Mouse Mysz Up Góra Down Dół Left Lewo Right Prawo LB LB MB MB RB RB Pause Przerwa Hold Przytrzymanie Cycle Cykl Distance Odległość Release Zwolnienie Mouse Mod Tryb myszki Press Time Przytrzymanie okresowo Delay Opóźnienie Load %1 Załadowanie %1 Set Change %1 Zmiana ustawienia %1 [Text] %1 [Text] %1 [Exec] %1 [Exec] %1 [NO KEY] [BRAK] JoyControlStick Stick Joystick analogowy JoyControlStickButton Up Góra Down Dół Left Lewo Right Prawo Button Przycisk JoyControlStickContextMenu Mouse (Normal) Mysz (standardowo) Mouse (Inverted Horizontal) Mysz (w odwróconym poziomie) Mouse (Inverted Vertical) Mysz (w odwróconym pionie) Mouse (Inverted Horizontal + Vertical) Mysz (w odwróconym poziomie + pionie) Arrows Strzałki Keys: W | A | S | D Klawisze: W | A | S | D NumPad Klawisze numeryczne None Brak Standard Standard Eight Way Ośmioosiowo 4 Way Cardinal w 4 głównych kierunkach 4 Way Diagonal w 4 głównych przekątnych Mouse Settings Ustawienia myszki JoyControlStickEditDialog Dialog Okno dialogowe X: X: 0 0 Y: Y: Distance: Odległość: Bearing: Łożysko: % Safe Zone: % strefa bezpieczna: Presets: Predefinicje: Mouse (Normal) Mysz (standardowo) Mouse (Inverted Horizontal) Mysz (w odwróconym poziomie) Mouse (Inverted Vertical) Mysz (w odwróconym pionie) Mouse (Inverted Horizontal + Vertical) Mysz (w odwróconym poziomie + pionie) Arrows Strzałki Keys: W | A | S | D Klawisze: W | A | S | D NumPad Klawisze numeryczne None Brak Stick Mode: Tryb joysticka analogowego: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Standardowo: Ośmiokierunkowy analog z dwoma aktywnymi przyciskami nakierowującymi, gdy analog jest zwrócony w kierunku ukośnym. Ośmioosiowo: Ośmiokierunkowy analog z ośmioma przyciskami. Tylko jeden przycisk jest aktywny w tym samym czasie. Opcja jest przydatna w przypadku gier podobnych do Rogue. W 4 głównych kierunkach: Czterokierunkowy analog z kierunkami odwołującymi się do głównych kierunków świata. Opcja jest przydatna w przypadku menu W 4 głównych przekątnych: Czterokierunkowy analog z kierunkami odwołującymi się do stref przekątnych analogu. Standard Standardowo Eight Way Ośmioosiowo 4 Way Cardinal W 4 głównych kierunkach 4 Way Diagonal W 4 głównych przekątnych Dead Zone: Martwa strefa: Modifier Zone: Dead zone value to use for an analog stick. Wartość martwej strefy dla zastosowania w joysticku analogowym. Max Zone: Maksymalna strefa: Value when an analog stick is considered moved 100%. Wartość określająca analog, którego kursor przekroczył 100%. Diagonal Range: Zakres przekątnej: The area (in degrees) that each diagonal region occupies. Powierzchnia (w stopniach), która zajmuje każdy przekątny kierunek. Square Stick: Czterokierunkowy analog: Percentage to modify a square stick coordinates to confine values to a circle Zmiana współrzędnych czterokierunkowego analogu dla ograniczenia wartości do koła, określona w procentach % % Stick Delay: Opóźnienie drążka: Time lapsed before a direction change is taken into effect. Czas, który upłynął przed wykryciem zmiany kierunku. s s Modifier: Modyfikator: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Przycisk edycji, który jest aktywny w trakcie, gdy i drążek jest aktywny. Ten przycisk jest przydatny dla przypisywania stref z klawiszami modyfikatora, które mogą być użyte do przypisania funkcji chodzenia/biegania do drążka analogowego. PushButton Przycisk Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Na&zwa: Specify the name of an analog stick. Określ nazwę joysticka analogowego. Mouse Settings Ustawienia myszki Set Ustaw Set %1 Zestawienie %1 JoyControlStickModifierButton Modifier Modyfikator JoyDPad DPad Pad kierunkowy JoyDPadButton Up Góra Down Dół Left Lewo Right Prawo Button Przycisk JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Przycisk JoySensorContextMenu Mouse Settings Ustawienia myszki JoySensorEditDialog Dialog Okno dialogowe 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % strefa bezpieczna: Presets: Predefinicje: Dead Zone: Martwa strefa: Dead zone value to use for an analog sensor. Max Zone: Maksymalna strefa: Value when an analog sensor is considered moved 100%. Diagonal Range: Zakres przekątnej: The area (in degrees) that each diagonal region occupies. Powierzchnia (w stopniach), która zajmuje każdy przekątny kierunek. Sensor Delay: Time lapsed before a direction change is taken into effect. Czas, który upłynął przed wykryciem zmiany kierunku. s s Na&me: Specify the name of an analog sensor. Mouse Settings Ustawienia myszki Roll (°/s) Pitch (°/s) Yaw (°/s) Set Ustaw Set %1 Zestawienie %1 JoySensorPreset None Brak Mouse (Normal) Mysz (standardowo) Mouse (Inverted Horizontal) Mysz (w odwróconym poziomie) Mouse (Inverted Vertical) Mysz (w odwróconym pionie) Mouse (Inverted Horizontal + Vertical) Mysz (w odwróconym poziomie + pionie) Arrows Strzałki Keys: W | A | S | D Klawisze: W | A | S | D NumPad JoyTabWidget <New> <Nowy> Battery level of controller Remove Usuń Remove configuration from recent list. Usuń konfigurację z ostatniej listy. Load Załaduj Load configuration file. Załaduj plik konfiguracyjny. Save Zapisz Save changes to configuration file. Zapisz zmiany do pliku konfiguracyjnego. Save As Zapisz jako Save changes to a new configuration file. Zapisz zmiany do nowego pliku konfiguracyjnego. Sets Zestawienia Copy from Set Kopiuj z zestawienia Settings Ustawienia Set 1 Zestawienie 1 Set 2 Zestawienie 2 Set 3 Zestawienie 3 Set 4 Zestawienie 4 Set 5 Zestawienie 5 Set 6 Zestawienie 6 Set 7 Zestawienie 7 Set 8 Zestawienie 8 Stick/Pad Assign Przypisywanie do Joysticka/Gamepada Controller Mapping Mapowanie kontrolera Quick Set Szybkie ustawienie Names Nazwy Toggle button name displaying. Przełącz wyświetlanie nazwy przycisku. Pref Pref Change global profile settings. Zmień globalne ustawienia dla profilu. Reset Reset Revert changes to the configuration. Reload configuration file. Przwróć zmiany w konfiguracji. Przeładuj plik konfiguracyjny. Open Config Otwórz konfigurację Config Files (*.amgp *.xml) Pliki konfiguracyjne (*.amgp *.xml) Save Config Zapisz konfigurację Config File (*.%1.amgp) Plik konfiguracyjny (*.%1.amgp) Do you really want to reset buttons settings for joystick? Czy na pewno chcesz zresetować ustawienia dla przycisków joystick'a? Set Ustaw Save Profile Changes? Zapisać zmiany dla profilu? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Zmiany dla nowego profilu nie zostały zapisane. Czy chcesz, aby aktualny profil został zapisany lub usunięty? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Zmiany dla profilu "%1" nie zostały zapisane. Czy chcesz, aby zmiany dla aktualnego profilu zostały zapisane lub usunięte? Sticks Joysticki analogowe Sensors DPads Pady kierunkowe No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Nie wykryto żadnych przypisywanych przycisków. Użyj okna szybkiego ustawiania, by przypisać znaki klawiszy do przycisków lub zablokuj ukrywanie pustych przycisków. Set %1: %2 Zestawienie %1: %2 Set %1 Zestawienie %1 Copy Set Assignments Skopiuj zestawienie przypisań Are you sure you want to copy the assignments and device properties from %1? Czy na pewno chcesz skopiować przypisania i właściwości urządzenia z %1? Joystick Joystick Joystick JoystickStatusWindow Properties Właściwości Details Szczegóły Name: Nazwa: %1 %1 Number: Numer: Axes: Osie: Buttons: Przyciski: Hats: Przyciski POV: Sensors: Battery: Bateria: Unknown Nieznany GUID: GUID: Game Controller: Kontroler: Axes Osie Buttons Przyciski Hats Przyciski POV Sensors %1 (#%2) Properties %1 (#%2) Właściwości Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None Brak Axis %1 Oś %1 Hat %1 Przycisk POV %1 No Nie Yes Tak MainSettingsDialog Edit Settings Zmień ustawienia General Ogólnie Controller Mappings Mapowania kontrolera Language Język Auto Profile Profil automatyczny Mouse Mysz Advanced Zaawansowany Pro&file Directory: Kat&alog profilu: <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Określ domyślną ścieżkę, aby program mógł go użyć w innych oknach podczas ładowania profilu lub zapisywania nowego.</p></body></html> Recent Profile Count: Liczba ostatnich profili: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Liczba profili, które mogą być umieszczone na liście ostatnich profili. 0 będzie skutkowało tym, że limit dla liczby wyświetlanych profili nie będzie w ogóle narzucany.</p></body></html> Gamepad Poll Rate: Szybkość wysyłania sygnałów gamepada: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Zmień szybkość wysyłania sygnałów, które program używa, by przechwytywać nowe zdarzenia z gamepada. Domyślnie wartość wynosi 10 ms. Zmniejszenie szybkośći wysyłania sygnałów mogłoby spowodować większe zużycie mocy procesora. Wysoce rekomendowane jest przeprowadzenie testów ustawień przed użyciem AntiMicroX. Hide main window when the main window close button is clicked instead of quitting the program. Ukryj główne okno, a nie zamykaj, gdy wybierany jest przycisk zamykania okna. Close To Tray Zamknij w tacce systemowej Have Windows start AntiMicroX at system startup. Uruchom AntiMicroX przy uruchomieniu systemu. Launch At Windows Startup Uruchom przy starcie Windows Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Wyświetl ostatnie profile dla wszystkich kontrolerów w postaci pojedynczej listy w menu zasobnika systemowego. Domyślnie dla użycia podmenu. Single Profile List in Tray Pojedyncza lista profilu w tacce systemowej Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Zminimalizuj program do paska zadań. Domyślnie program jest minimalizowany do tacki systemowej jeśli jest to możliwe. Minimize to Taskbar Zminimalizuj do paska zadań This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Ta opcja spowoduje schowanie wszystkich nieprzypisanych przycisków w aplikacji. Zajdzie potrzeba użycia okna szybkiego ustawiania, by pojawiło się okno edytowania dla przycisków gamepada. Hide Empty Buttons Ukryj puste przyciski When the program is launched, open the last known profile that was opened during the previous session. Gdy program jest już uruchomiony, otwórz ostatni znany profil, który był otwierany podczas poprzedniej sesji. Auto Load Last Opened Profile Automatycznie ładuj ostatni otwarty profil Only show the system tray icon when the program first launches. Pokazuj jedynie ikonę w tacce systemowej, gdy program się uruchamia. Launch in Tray Uruchom w tacce systemowej Associate .amgp files with AntiMicroX in Windows Explorer. Skojarz pliki .amgp z AntiMicroX w eksploratorze Windows. Associate Profiles Skojarz profile Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Pamiętaj, że nie będzie działać, jeśli nie masz takiej klawiatury podłączonej do komputera lub jeśli nie jest ona wbudowana jak w komputerach stacjonarnych Attach the numeric keypad Podłącz klawiaturę numeryczną Key Repeat Powtarzanie klawisza Active keys will be repeatedly pressed when this option is enabled. Aktywne klawisze będą wielokrotnie naciskane gdy ta opcja zostanie zaznaczona. Enable Odblokuj Delay: Opóźnienie: Specifies how much time should elapse before key repeating begins. Określa, ile czasu musi upłynąć, zanim nastąpi powtarzanie przycisku klawisza. ms ms Rate: Tempo: Specifies how many times key presses will be performed per seconds. Określa, ile razy na sekundę klawisz będzie naciskany automatycznie. times/s raz/y Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. Poniżej znajduje się lista zapisanych mapowań. Możesz użyć podanej tabeli, by usunąć mapowania lub je tymczasowo zablokować. Możesz także zablokować mapowania, które są zawarte z biblioteką SDL; wystarczy wprowadzenie nowego rzędu z odpowiednim GUID joysticka i zaznaczenie blokady. Ustawienia nie będą miały wpływu o ile nie zostaną odświeżone wszystkie joysticki lub nie zostanie odpięty konkretny joystick. GUID GUID Mapping String Mapowanie tekstowe Disable? Zablokować? Delete Usuń <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntiMicroX został przetłumaczony na wiele innych języków przez kilku woluntariuszy. Domyślnie program wybierze odpowiednie tłumaczenie oparte na ustawieniach lokalnych systemu. Jednakże możliwy jest wybór innego języka, który znajduje się na liście poniżej.</p></body></html> Default Domyślny Português do Brasil Português do Brasil English English Français Français Deutsch Deutsch Italiano Italiano 日本語 日本語 Русский Русский српски / srpski српски / srpski 简体中文 简体中文 Español Español українська українська Polski Polski Active Aktywny Devices: Urządzenia: All Wszystko Device Urządzenie Profile Profil Class Klasa Title Tytuł Program Program Default? Domyślnie? Add Dodaj Show low battery notification Show empty battery notification Edit Edytuj Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Zablokuj ustawienie "Rozszerzona precyzja kursora", podczas gdy AntiMicroX jest uruchomiony. Zablokowanie opcji "Rozszerzona precyzja kursora" pozwoli na bardziej precyzyjny ruch myszki wewnątrz AntiMicroX. Disable Enhance Pointer Precision Zablokuj rozszerzoną precyzję myszki Smoothing Wygładzanie History Si&ze: Rozmia&r historii: Weight Modi&fier: Mody&fikator wagowy: Note: To see the change of log level in console output (not in log file), application restart is required Uwaga: Aby zobaczyć logi w konsoli (nie w wybranym pliku), wymagany jest restart aplikacji Reset Reset Refresh Rate: Częstotliwość odświeżania: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Częstotliwość odświeżania jest ilością czasu, jaka upłynie pomiędzy występowaniem zdarzeń myszki. Zaleca się ostrożnie stosować tę opcję, ponieważ może spowodować większe zużycie mocy procesora. Ustawienie wartości zbyt niskiej wywoła destabilizację systemu. Silnie zaleca się przetestowanie ustawienia przed jego użyciem. Spring Tekst Screen: Ekran: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Wykorzystaj określony wyświetlacz dla trybu tekstowego. Na Linux, domyślnie używany jest główny ekran. Na Windows, domyślnie używane są wszystkie dostępne ekrany. Accel Numerator: Licznik przyspieszenia: 0 0 Accel Denominator: Mianownik przyspieszenia: Accel Threshold: Granica przyspieszenia: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Jeżeli wartości przyspieszenia dla wirtualnej myszki nie zostały zmienione przez odmienny proces, szczególnie w trakcie wyłącznia starszej gry, to możesz chcieć zresetować wartości przyspieszenia stosowane przez wirtualną myszkę. Reset Acceleration Resetuj przyspieszenie Log File: Plik z logami: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: Poziom logów: None Brak Error Błąd Warning Ostrzeżenie Info Informacja Verbose Debug Debugowanie AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Również użytkownicy systemu Windows, którzy chcą zastosować niską wartość, powinni także sprawdzić opcję "Zablokuj rozszerzoną precyzję myszki", jeżeli nie chcą mieć zablokowanej tej opcji w Windows. Select Default Profile Directory Zaznacz domyślny katalog profilu Are you sure you want to delete the profile? Czy na pewno usunąć ten profil? Save Log File As Zapisz plik z logami jako Log Files (*.log) Pliki z logami (*.log) Do you really want to reset setting? Czy na pewno chcesz zresetować ustawienia? Would you like to reset mappings too? Czy chcesz także zresetować ustawienia mapowania? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu Nie znaleziono żadnego joysticka. Podłącz joystick a następnie wybierz opcję "Zaktualizuj joysticki" w głównym menu If events are not seen by a game, please click here to run this application as Administrator. Jeśli zdarzenia nie są wykrywane przez grę, kliknij tutaj, by uruchomić aplikację w trybie administratora. Update Button &App &Aplikacja &Options &Opcje He&lp Po&moc &Quit &Zakończ Ctrl+Q Ctrl+Q &Update Joysticks &Zaktualizuj joysticki Ctrl+U Ctrl+U &Hide &Ukryj Ctrl+H Ctrl+H &About &O programie Ctrl+A Ctrl+A About &Qt O &Qt Ctrl+T Ctrl+T &Properties &Właściwości Ctrl+P Ctrl+P &Key Checker &Sprawdzanie klawiszy Ctrl+K Ctrl+K Home Page Strona domowa &GitHub Page &Strona na Github Ctrl+G Ctrl+G S&ettings U&stawienia Ctrl+S Ctrl+S &Stick/Pad Assign &Przypisywanie do Joysticka/Gamepada Ctrl+X Ctrl+X &Wiki &Wiki Ctrl+W Ctrl+W &Issues &Błędy Ctrl+I Ctrl+I &Calibration &Kalibracja Ctrl+C Ctrl+C (%1) (%1) Open File Otwórz plik Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. Czy na pewno chcesz uruchomić ten program jako Administrator? Niektóre gry są uruchamiane jako Administrator, co powoduje, że zdarzenia generowane przez program antimicro nie są wykorzystywane przez te gry, chyba że program antimicro jest również uruchamiany jako Administrator. Wynika to z problemów z uprawnieniami spowodowanych przez opcje Kontroli konta użytkownika (UAC) w systemie Windows Vista i nowszych. %1 battery %1 bateria Battery level is less than %1 Poziom baterii jest niższy niż %1 Device number: %1 Device name: %2 Numer urządzenia: %1 Nazwa urządzenia: %2 Update to %1 available Reading old profile Odczyt starego profilu This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore &Przywracanie Calibration couldn't be opened Okno kalibracji nie mogło zostać otwarte You must connect at least one controller to open the window Wymagane jest podłączenie co najmniej jednego kontrolera przed próbą otworzenia okna Run as Administrator? Uruchomić jako administrator? Failed to elevate program Podniesienie programu zakończyło się niepowodzeniem Failed to restart this program as the Administrator Ponowne uruchomienie programu w trybie administratora zakończyło się niepowodzeniem MouseAxisSettingsDialog Mouse Settings - Ustawienia Myszki - Set %1 Zestawienie %1 MouseButtonSettingsDialog Mouse Settings - Ustawienia msyzki - Set %1 Zestawienie %1 MouseControlStickSettingsDialog Mouse Settings Ustawienia myszki Set %1 Zestawienie %1 MouseDPadSettingsDialog Mouse Settings Ustawienia myszki Set %1 Zestawienie %1 MouseSensorSettingsDialog Mouse Settings Ustawienia myszki Set %1 Zestawienie %1 MouseSettingsDialog Mouse Settings Ustawienia myszki Mouse Mode: Tryb myszki: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Tryb kursora jest używany do poruszania kursorem myszki po ekranie w odniesieniu do jego aktualnej pozycji w zależności jak intensywnie poruszasz się po osi lub jak intensywnie naciskany jest przycisk. Tryb tekstowy jest używany do poruszania kursorem myszki od środka ekranu w zależności jak bardzo poruszasz nią wzdłuż osi. Kursor myszki będzie wracał na środek ekranu za każdym razem, gdy odległość wzdłuż osi, którą pokonałeś ruchem myszki przekroczy ustaloną granicę. Cursor Kursor Spring Tekst Acceleration: Akceleracja: Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Rozszerzony: Trzeci stopień krzywej, który sprawia, że ruch myszki zwalnia przy początku osi i przyspiesza przy jego końcu. Liniowy: Kursor myszki porusza się proporcjonalnie do osi. Kwadratowy: Kursor myszki przyspiesza wolno na początku osi. Sześcienny: Ruch myszki przyspiesza wolniej niż w trybie kwadratowym (czyli krzywej drugiego stopnia). Skrajnie kwadratowy: Zwiększa prędkość ruchu myszki 1.5 razy dopóki nie osiągnie 95% zamierzonego odcinka Funkcja mocy: Pozwala na użycie bardziej tradycyjnej opcji krzywej. Łagodnie kwadratowy: Poziom końcowy osi przyspiesza stopniowo przez określony czas z zastosowaniem krzywej drugiego stopnia. Łagodnie sześcienny: Poziom końcowy osi przyspiesza stopniowo przez określony czas z zastosowaniem krzywej trzeciego stopnia. Enhanced Precision Rozszerzona precyzja Linear Liniowa (krzywa I stopnia) Quadratic Kwadratowa (krzywa II stopnia) Cubic Sześcienna (krzywa III stopnia) Quadratic Extreme Skrajnie kwadratowa Power Function Funkcja mocy Easing Quadratic Łagodnie kwadratowa Easing Cubic Łagodnie sześcienna Mouse Speed Settings Ustawienia prędkości myszki Enable to change the horizontal and vertical speed boxes at the same time. Możliwa zmiana prędkości poziomej i pionowej skrzyń w tym samym czasie. Change Together Zmiany całościowe Hori&zontal Speed: Prę&dkość pozioma: 1 = 20 pps 1 = 20 pps &Vertical Speed: &Prędkość pionowa: Wheel Hori. Speed: Kierownica Hori. Prędkość: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Ustawia prędkość poziomego ruchu rolki myszki według liczby symulowanych kroków na sekundę. 1 = 1 notch(es)/s 1 = 1 obrót(y)/ów Wheel Vert. Speed: Kierownica pionowa. Prędkość: Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Ustawia prędkość pionowego ruchu rolki myszki według liczby symulowanych kroków na sekundę. Sensitivit&y: Czułoś&ć: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Przeznaczone dla funkcji mocy. Określa czynnik dla zastosowania czułości krzywej. Gdy wartość przekracza 1.0, ruch myszki ulegnie większemu przyspieszeniu na niskim poziomie osi. Easing Duration: Zmniejszenie trwania: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. Określa ilość czasu (w sekundach) wymaganą przed pełnym przyspieszeniem myszy i po osiągnięciu końcowego odcinka osi. s s Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Opcje dodania lepszego przyspieszenia ruchu myszki poza tym, co krzywa przespieszenia mogłaby wyprodukować. Przyspieszenie jest dodawane na podstawie tego, jak szybko następuje ruch osi. Opcja została stworzona w celu wyeliminowania pewnych błędów związanych z bardzo ograniczoną dostępnością do przedziału wartości, używając standardowych przycisków analogowych. Delta Acceleration Przyspieszenie delta &Multiplier: &Mnożnik: Highest value to accelerate mouse movement by Największa wartość przyspieszenia ruchu myszki x x Start %: Start %: Acceleration begins at this percentage of the base multiplier Przyspiesznie rozpoczyna się na tym poziomie procentowym głównego mnożnika % % Mi&n Threshold: Mi&nimalna granica: Minimum amount of axis travel required for acceleration to begin Minimum dla ilości przesuwu osi, wymaganej do rozpoczęcia przyspieszenia Max Threshold: Maksymalna granica: Maximum axis travel before acceleration has reached the multiplier value Maksimum dla przesuwu osi, potrzebnego dla momentu, zanim przyspiesznie osiągnie wartość mnożnika E&xtra Duration: Do&datkowy czas trwania: Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Rozszerzenie przedziału czasowego dla dodania dodatkowego przyspieszenia. Przesuw osi zostanie przeniesiony do konta. Wolniejszy ruch zmniejszy aktualny czas, by mogło zostać dodane dodatkowe przyspieszenie. Curve: Krzywa: Ease Out Sine Zwalnianie pod koniec Ease Out Quad Większe zwalnianie pod koniec Ease Out Cubic Zwalnianie pod koniec plus większe przyspieszenie Spring Settings Ustawienia tekstu Spring Width: Szerokość tekstu: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Zmienia szerokość regionu tak, aby kursor mógł poruszać się w trybie tekstowym. 0 będzie używało całej szerokości twojego ekranu. Spring Height: Wysokość tekstu: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. Zmienia wysokość regionu tak, aby kursors mógł poruszać się w trybie sprężyny. 0 będzie używało całej szerokości twojego ekranu. Release Radius: Zwalnianie zasięgu: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Określa, czy pole tekstowe będzie zależne od pozycji kursora myszki, ustawionej przez niezależny tekst. Relative Względny Mouse Status Status myszki X: X: 0 (0 pps) 0 (0 pps) Y: Y: %n notch(es)/s %n obrót %n obroty %n obrotów QKeyDisplayDialog Key Checker Detekcja klawiszy <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Procedura obsługi zdarzenia: Native Key Value: Wartość klawisza natywnego: 0x00000000 0x00000000 Qt Key Value: Wartość klawisza Qt: antimicro Key Value: Wartość klawisza AntiMicroX: QObject Last button Ostatni przycisk There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Program nie wykrywa ostatniego przypisanego przycisku. Czy co najmniej jeden przycisk został zmapowany z klawiatury do gamepad'a? # of joysticks found: %1 # joystick'ów zostało znalezionych: %1 List Joysticks: Lista joystick'ów: --------------- --------------- Joystick %1: Joystick %1: Unknown log level: Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Lokalizacja profilu %1 nie wskazuje na plik typu XML. Profile location %1 does not exist. Profil %1 nie istnieje. Controller identifier is not a valid value. Identyfikator kontrolera nie należy do wartości prawidłowych. An invalid set number '%1' was specified. Została określona nieprawidłowa liczba '%1". Controller identifier '%s'' is not a valid value. Identyfikator kontrolera '%s'' nie jest wartością prawidłową. No set number was specified. Nie została określona ustalona liczba. An invalid event generator was specified. Został określony nieprawidłowy generator zdarzeń. No event generator string was specified. Nie został określony generator zdarzeń. No log file specified. Nie został określony plik z logami programu. Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Attempting to use fallback option %1 for event generation. Próba użycia awaryjnej opcji %1 dla generatora zdarzeń. Failed to open event generator. Exiting. Uruchomienie generatora zdarzeń zostało zakończone niepowodzeniem. Koniec. Using %1 as the event generator. Zastosowanie %1 jako generatora zdarzeń. Quitting Program Zamykanie aplikacji Super Super Menu Menu Mute Mute Vol+ Vol+ Vol- Vol- Play/Pause Play/Pause Play Play Pause Pause Prev Prev Next Next Mail Mail Home Home Media Media Search Search xinput version must be at least 2.0. No mouse acceleration changes will occur. wersja rozszerzenia xinput nie może być mniejsza od 2.0. Zmiany przy akceleracji myszki nie zostaną uwzględnione. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set Szybkie ustawienie <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>Naciśnij przycisk lub wykonaj ruch w kierunku osi %1 (<span style=" font-weight:600;">%2</span>).<br/>Pojawi się okno dialogowe<br/>które odblokuje możliwość tworzenia zadań.</p></body></html> Quick Set %1 Szybkie ustawienie %1 SetAxisThrottleDialog Throttle Change Zmiana przepustnicy analogowej The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? Ustawienie przepustnicy dla osi %1 zostało zmienione. Czy nowe ustawienia przepustnicy mają zostać uwzględnione we wszystkich zestawieniach? SetJoystick Set %1: %2 Zestawienie %1: %2 Set %1 Zestawienie %1 SetNamesDialog Set Name Settings Ustawienia nazw zestawień Set 1 Zestawienie 1 Set 2 Zestawienie 2 Set 3 Zestawienie 3 Set 4 Zestawienie 4 Set 5 Zestawienie 5 Set 6 Zestawienie 6 Set 7 Zestawienie 7 Set 8 Zestawienie 8 Name Nazwa SimpleKeyGrabberButton Mouse Mysz SpringModeRegionPreview Spring Mode Preview Podgląd trybu tekstowego UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Nie można odnaleźć poprawnego pliku dla uinput. Sprawdź, czy moduł uinput został odpowiednio wczytany. Przykładowe polecenie sprawdzające: lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Nie można otworzyć pliku dla uinput. Sprawdź uprawnienia zapisu dla pliku Using uinput device file %1 Zastosowanie pliku %1 dla uinput UInputHelper a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z Esc Esc F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace BackSpace Tab Tab [ [ ] ] \ \ CapsLock CapsLock ; ; ' ' Enter Enter Shift_L Shift_L , , . . / / Ctrl_L Ctrl_L Super_L Super_L Alt_L Alt_L Space Space Alt_R Alt_R Menu Menu Ctrl_R Ctrl_R Shift_R Shift_R Up Góra Left Lewo Down Dół Right Prawo PrtSc PrtSc Ins Ins Del Del Home Home End End PgUp PgUp PgDn PgDn NumLock NumLock * * + + KP_Enter KP_Enter KP_1 KP_1 KP_2 KP_2 KP_3 KP_3 KP_4 KP_4 KP_5 KP_5 KP_6 KP_6 KP_7 KP_7 KP_8 KP_8 KP_9 KP_9 KP_0 KP_0 SCLK SCLK Pause Pause Super_R Super_R Mute Mute VolDn VolDn VolUp VolUp Play Play Stop Stop Prev Prev Next Next [NO KEY] [BRAK] UnixWindowInfoDialog Captured Window Properties Uchwycone właściwości okna Information About Window Informacje o oknie Class: Klasa: TextLabel Etykieta Title: Tytuł: Path: Ścieżka: Match By Properties Dopasowanie według właściwości Class Klasa Title Tytuł Path Ścieżka VDPad VDPad VDPad VirtualKeyPushButton Space Space Tab Tab Shift (L) Shift (L) Shift (R) Shift(R) Ctrl (L) Ctrl (L) Ctrl (R) Ctrl (R) Alt (L) Alt (L) Alt (R) Alt (R) Alt Gr Alt Gr ` ` ~ ~ - - = = [ [ ] ] \ \ Caps Caps ; ; ' ' , , . . / / ESC ESC PRTSC PRTSC SCLK SCLK INS INS PGUP PGUP DEL DEL PGDN PGDN 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK NUM LK * * + + Enter Enter Del Del < < : : Super (L) Super (L) Menu Menu Up Góra Down Dół Left Lewo Right Prawo VirtualKeyboardMouseWidget Keyboard Klawiatura Mouse Mysz Left Mouse Myszki Lewo Up Mouse Myszki Góra Left Button Mouse Myszki Lewy przycisk Middle Button Mouse Myszki Środkowy przycisk Right Button Mouse Myszki Prawy przycisk Wheel Up Mouse Rolką w górę Wheel Left Mouse Rolką w lewo Wheel Right Mouse Rolką w prawo Wheel Down Mouse Rolką w dół Down Mouse Myszki Dół Right Mouse Myszki Prawo Button 4 Mouse Przycisk 4 Mouse 8 Mouse Przycisk myszy 8 Button 5 Mouse Przycisk 5 Mouse 9 Mouse Przycisk myszy 9 Mouse Settings Ustawienia myszki NONE BRAK [NO KEY] [BRAK] Last button Ostatni przycisk Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Sloty dla wprowadzonych przycisków nie mogły zostać usunięte, ponieważ żadne dane nie zostały dotychczas wprowadzone z układu klawiatury do układu gamepad'a. Stwórz mapowanie co najmniej jednego przycisku dla gamepad'a Others Inne Applications Aplikacje Browser Back Browser Back Browser Favorites Browser Favorites Browser Forward Browser Forward Browser Home Browser Home Browser Refresh Browser Refresh Browser Search Browser Search Browser Stop Browser Stop Calc Calc Email Email F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media Media Media Next Media Next Media Play Media Play Media Previous Media Previous Media Stop Media Stop Search Search Volume Down Volume Down Volume Mute Volume Mute Volume Up Volume Up VirtualMousePushButton INVALID NIEPRAWIDŁOWY WinAppProfileTimerDialog Capture Application Zrzut aplikacji After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Jeśli wybrałeś "Zrzut aplikacji", kliknij na okno dowolnej otwartej aplikacji, aby twój profil został z nim powiązany. Otwarta aplikacja zostanie uchwycona po podanym czasie. Timer: Licznik: Seconds Sekund Cancel Anuluj WinExtras [NO KEY] [BRAK] AntiMicro Profile X11Extras ESC ESC Tab Tab Space Space DEL DEL Return Return KP_Enter KP_Enter Backspace Backspace Alt Gr Alt Gr xinput extension was not found. No mouse acceleration changes will occur. rozszerzenie xinput nie zostało znalezione. Zmiany przy akceleracji myszki nie zostaną uwzględnione. xinput version must be at least 2.0. No mouse acceleration changes will occur. wersja rozszerzenia xinput nie może być mniejsza od 2.0. Zmiany przy akceleracji myszki nie zostaną uwzględnione. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 PtrFeedbackClass nie została znaleziona dla wskażnika wirtualnego. Zmiany akceleracji myszki nie zostaną uwzględnione dla urządzenia o id=%1 Changing mouse acceleration for device with id=%1 Zmiana akceleracji myszki dla urządzenia o numerze id=%1 XMLConfigReader Could not write updated profile XML to file %1. Zapis zaktualizowanego profilu XML do pliku %1 jest niemożliwy. XMLConfigWriter Could not write to profile at %1. Zapis do profilu %1 był niemożliwy. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Aplikacja z nakładką graficzną do importowania ustawień przycisków klawiatury i myszki do gamepad'a. Program jest szczególnie przydatny dla gier bez wbudowanego wsparcia dla gamepad'ów. main Launch program in system tray only. Uruchom program w tacce systemowej. Launch program with the tray menu disabled Uruchom program bez udziału tacki systemowej Launch program without the main window displayed Uruchom program pomijając wyświetlenie głównego okna Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location lokalizacja Apply configuration file to a specific controller. Value can be a controller index, name, or GUID Wybierz plik konfiguracyjny dla wskazanego kontrolera. Wartością może być indeks kontrolera, nazwa lub GUID value wartość Unload currently enabled profile(s) Odłącz aktualnie odblokowany profil(e) value(s) wartość(i) Start joysticks on a specific set. Value can be a controller index, name, or GUID Uruchom joystick(i) z numerem ustawienia. Wartością może być indeks kontrolera, nazwa lub GUID number value numer wartość Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type typ-logów Choose a file for logs writing Wybierz plik dla zapisywania logów filename nazwaPliku Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. Choose between using XTest support and uinput support for event generation. Default: xtest. Wybierz między wsparciem xtest a wsparciem uinput dla generatora zdarzeń. Do zastosowania wyłącznie w przypadku wykrywania przez program xtest oraz uinput pod Linux oraz w przypadku wykrywania opcji vmulti pod Windows. Domyślnie: xtest. event-generation-type typ-generatora-zdarzeń Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. Wyświetl informacje o wykrytych joystick'ach przez bibliotekę SDL. Zastosowanie wyłącznie z dostępną i odblokowaną biblioteką sdl. Wyświetlane informacje dotyczą indeksu kontrolerów, nazw i GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_pt.ts000066400000000000000000013456311471077622000274170ustar00rootroot00000000000000 AboutDialog About sobre Version versión <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Desenvolvido originalmente por Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Em seguida mantido pelo grupo AntiMicro em https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Depois por juliagoda em https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Agora mantido por https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contribuidores:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Tradutores:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Português do Brasil</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">TimeCop 'Em Master&lt;timecop5020@gmail.com&gt; - Português do Brasil</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinês</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - Francês</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - Alemão</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - Alemão</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japonês</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russo</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Sérvio</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ucraniano</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Espanhol</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italiano</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polonês</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Copyright: 2013 - 2022 Info info <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> Changelog Changelog Credits Créditos AntiMicroX AntiMicroX About Development Sobre el desenvolvimiento License Licencia Program Version %1 Versión del programa %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Programa compilado en %1 a %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Usando Qt %1 Using Event Handler: %1 Usando Gestor de Eventos: %1 AddEditAutoProfileDialog Auto Profile Dialog Diálogo de perfil automático Pro&file: Per&fil: Browse Navegar Window: ventana: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Selecione Janela. Clique na janela da aplicação certa e o caminho do ficheiro da aplicação será preenchido na forma. Detect Window Properties Detectar Propriedades da Janela &Class: &Classe: T&itle: T&itulo: set partial title inserir titulo parcial Application: Aplicación: Select seleccione De&vices: Di&spositivos: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Selecione esse perfil para ser carregado por padrão pelo dispositivo especifico. A seleção vai ser usada ao invés de todas as opções de perfil padrão. Set as Default for Controller Definir como Padrão para o Controle A different profile is already selected as the default for this device. Um perfil diferente já está selecionado para esse dispositivo. Current (%1) Atual (%1) Open Config Abrir Config Select Program Seleccionar Programa Programs (*.exe) Programas (*.exe) Please use the main default profile selection. Por favor, utilice la selección principal perfil predeterminado. Main Profile Perfil Principal Already selected Já Selecionado Chosen Profile Perfil Escolhido The selection will be used instead of the all default profile option. A seleção vai ser usada ao invés de todas as opções de perfil padrão. Please select a window by using the mouse. Press Escape if you want to cancel. Por favor, seleccione una ventana utilizando el ratón. Presione Escape si desea cancelar. Capture Application Window Capturar Janela de Aplicativo Could not obtain information for the selected window. Não foi possível obter informação para a janela selecionada. Application Capture Failed Captura de Aplicativo falhou Profile file path is invalid. La ruta de archivo de perfil es invalido. No window matching property was specified. Nenhuma janela com propriedades compatíveis foi especificada. Program path is invalid or not executable. Caminho do programa é inválido ou não executável. File is not an .exe file. O ficheiro não é um ficheiro .exe. No window matching property was selected. Nenhuma janela com propriedades compatíveis foi selecionada. AdvanceButtonDialog Advanced Avanzado Assignments Asignamientos Toggle Alternar Turbo Turbo Set Selector Selector de Set Blank or KB/M Vacio o KB/M Hold Mantener Pause Pausa Cycle Ciclo Distance Distancia Insert Inserir Delete Apagar Clear All Limpar todo Time: Tempo: 0.01s 0.01s 0s 0s Insert a pause that occurs in between key presses. Insertar una pausa que se produce en la introducción de la tecla. Release Soltar Insert a new blank slot. Inserte una nueva ranura en blanco. Join Entrar Split Dividir Delete a slot. Borrar ranura. Clear all currently assigned slots. Limpiar todos los slots asignados actualmente. Specify the duration of an inserted Pause or Hold slot. Especificar la duración de una ranura de pausa o de retención insertado. 0m 0m &Mouse Speed Mod: &Mod. Vel. Rato: Specify the range past an axis dead zone in which a sequence of actions will execute. Especificar el rango más allá de una zona muerta eje en el que una secuencia de acciones se ejecutará. Distance: Distancia: % % Mouse Mod Raton Mod Press Time Tiempo de presionado Delay Retraso Execute Ejecutar Load Cargar Set Change Definir Cambio Text Entry Entrada de texto Placeholder marcador de posición 0 0 Set the percentage that mouse speeds will be modified by. Establecer el porcentaje que las velocidades de ratón serán modificadas por. Auto Reset Cycle After Auto Resetear Ciclos Después seconds segundos Executable: Executável: ... ... Arguments: Argumentos: Enabled Habilitado Mode: Modo: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>Normal:. Pulse y suelte repetidamente un botón por la tasa elegido </p><p> Gradiente: Modificar el retraso y liberación de un botón de acuerdo con la distancia de un eje se ha movido. La tasa seguirá siendo el mismo </p><p>Pulso:. Modifica como muchas veces un botón es presionado y liberado por segundo. El retraso botón seguirá siendo el mismo.</p></body></html> Normal Normal Gradient Gradiente Pulse Pulso Delay: Retraso: 0.10s 0.10s Rate: Taza: 10.0/s 10.0/s Disabled Inhabilitado Select Set 1 One Way Seleccione Set 1 Unidireccional Select Set 1 Two Way Seleccione Set 1 Bidireccional Select Set 1 While Held Seleccione Set 1 Mientras se Mantiene Select Set 2 One Way Seleccionar Set 2 Unidireccional Select Set 2 Two Way Seleccionar Set 2 Bidireccional Select Set 2 While Held Seleccionar Set 2 Mientras se Mantiene Select Set 3 One Way Seleccionar Set 3 Unidireccional Select Set 3 Two Way Seleccionar Set 3 Bidireccional Select Set 3 While Held Seleccionar Set 3 Mientras se Mantiene Select Set 4 One Way Seleccionar Set 4 Unidireccional Select Set 4 Two Way Seleccionar Set 4 Bidireccional Select Set 4 While Held Seleccionar Set 4 Mientras se Mantiene Select Set 5 One Way Seleccionar Set 5 Unidireccional Select Set 5 Two Way Seleccionar Set 5 Bidireccional Select Set 5 While Held Seleccionar Set 5 Mientras se Mantiene Select Set 6 One Way Seleccionar Set 6 Unidireccional Select Set 6 Two Way Seleccionar Set 6 Bidireccional Select Set 6 While Held Seleccionar Set 6 Mientras se Mantiene Select Set 7 One Way Seleccionar Set 7 Unidireccional Select Set 7 Two Way Seleccionar Set 7 Bidireccional Select Set 7 While Held Seleccionar Set 7 Mientras se Mantiene Select Set 8 One Way Seleccionar Set 8 Unidireccional Select Set 8 Two Way Seleccionar Set 8 Bidireccional Select Set 8 While Held Seleccionar Set 8 Mientras se Mantiene [NO KEY] [SEM TECLA] sec. Seg. /sec. /seg. Not checked slots Espaços não marcados To delete slots, you need to select at least one Para apagar espaços, você precisa selecionar ao menos um To insert slots, you need to select at least one Para inserir espaços, você precisa selecionar ao menos um Unknown current slot Espaço atual desconhecido Click on chosen slots before joining them Clique nos espaços selecionados antes de entrar neles Not enough slots Espaços insuficientes It's impossible to join slots. Add at least one other slot. É impossível entrar nos espaços. Adicione pelo menos um novo espaço. Not selected slots Não há espaços selecionados It's impossible to join slots. Select at least two slots before joining them É impossível juntar os espaços. Selecione pelo menos dois espaços antes de junta-los Only keyboard slots Somente espaços de teclado It's only possible to join simple and mix keyboard slots Só é possível juntar espaços de teclado simples e mistos It's impossible to split slots. Add at least one other slot. É impossível dividir os espaços. Adicione pelo menos um outro espaço. Not selected slot Espaço não selecionado Select your slot before splitting. Selecione um espaço antes de dividir. Too many mix slots São muitos espaços mistos Select one mix slot. Selecione um espaço para mistura. Only mix slots Somente misturar espaços It's only possible to split mix slot. Só é possível dividir espaços mistos. Empty execution path Espaço de execução vazio Line for execution file path is empty. Fill the first line before you are going to add a slot. Linha de caminho de execução está vazia. Preencha a primeira linha antes de adicionar a um espaço. File doesn't exist Ficheiro não existe There is no such file locally, that could be executed. Check the file on your system Nenhum ficheiro executável foi encontrado localmente. Verifique o ficheiro no seu sistema Set %1 Set %1 Select Set %1 Seleccionar Set %1 One Way Unidireccional Two Way Bidireccional While Held Mientras se Mantiene Choose Executable Escojer Ejecutable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Las ranuras mas allá de un Ciclo de acción podrán ser ejecutados en la proxima vez que se presione el botón. ciclos múltiples se pueden agregar con el fin de crear particiones en una secuencia. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Retrasa el momento en que la siguiente ranura es activado por el tiempo especificado. Las ranuras activadas antes de que el retraso se mantendrá activa una vez transcurrido el tiempo de retardo. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Distancia acción especifica que las ranuras después sólo se ejecutan cuando un eje se mueve de un cierto rango más allá de la zona muerta designada. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Inserte una acción de retención. Las ranuras después de la acción sólo se ejecutarán si el botón se mantiene más allá del intervalo especificado. Chose a profile to load when this slot is activated. Elija un perfil para cargar cuando se activa esta ranura. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. El Mod de acción del ratón va a modificar todos los ajustes de velocidad del ratón en un porcentaje especificado, mientras que la acción se está procesando. Esto puede ser útil para ralentizar el ratón para francotiradores. Specify the time that keys past this slot should be held down. Especificar el tiempo que las teclas pasan en esta ranura deben mantenerse presionadas. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Insertar una acción de liberación. Las ranuras después de la acción sólo se ejecutarán después de la liberación del botón si este fue presionado más allá del intervalo especificado. Change to selected set once slot is activated. Cambiar al set seleccionado una vez que se activa la ranura. Full string will be typed when a slot is activated. La cadena completa se tecleará cuando se activa una ranura. Execute program when slot is activated. Ejecutar el programa cuando se activa la ranura. Choose Profile Elegir Perfil Config Files (*.amgp *.xml) Ficheiros de Config (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Asignamiento de Palanca/Pad Sticks Palancas DPads DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. Obs: Essa janela é feita para trabalhar com compatibilidade com perfis feitos antes da versão 2.0 do Antimicro. Desde a versão 2.0, o uso da janela de mapeamento de controle é o método recomendado. %1 (Joystick %2) %1 (Mando %2) Stick 1 Palanca 1 Enabled Habilitar Assign Asignar X Axis: Eje X: Y Axis: Eje Y: Stick 2 Palanca 2 Number of Physical DPads: %1 Numero de DPads físicos: %1 Virtual DPad 1 DPad 1 Virtual Up: Arriba: Down: Abajo: Left: Izquierda: Right: Derecha: Axis %1 Ejes %1 Axis %1 - Ejes %1 - Axis %1 + Ejes %1 + Button %1 Botão %1 Move stick 1 along the X axis Mueva la palanca 1 a lo largo del eje X Move stick 1 along the Y axis Mueva la palanca 1 a lo largo del eje Y Move stick 2 along the X axis Mueva la palanca 2 a lo largo del eje X Move stick 2 along the Y axis Mueva la palanca 2 a lo largo del eje Y Press a button or move an axis Presione un botón o mueva un eje AxisEditDialog Axis Eixo Mouse (Horizontal) Rato (Horizontal) Mouse (Inverted Horizontal) Rato (Horizontal Invertido) Mouse (Vertical) Rato (Vertical) Mouse (Inverted Vertical) Rato (Vertical Invertido) Arrows: Up | Down Direcionais: Cima | Baixo Arrows: Left | Right Direcionais: Esquerda | Direita Keys: W | S Teclas: W | S Keys: A | D Teclas: A | D NumPad: KP_8 | KP_2 Teclado Numérico: 8 | 2 NumPad: KP_4 | KP_6 Teclado Numérico: 4 | 6 None Nenhum Set the value to use as the limit for an axis. Useful for a worn out analog stick. Establecer el valor a utilizar como límite para un eje. Útil para una palancas analógicas desgastadas. Negative Half Throttle Mitad de Acelerador Negativo Positive Half Throttle Mitad de Acelerador Positivo Haptic Trigger: Gatilho háptico: Name: Nombre: Specify the name of an axis. Especificar un nombre para un eje. Mouse Settings Configuraciones de Ratón Set the value of the dead zone for an axis. Establecer el valor de la zona muerta para un eje. Presets: Presets: Dead Zone: Zona morta: Max Zone: Zona Limite: [NO KEY] [SEM TECLA] Throttle setting that determines the behavior of how to interpret an axis hold or release. Ajuste del acelerador la que determina el comportamiento de la forma de interpretar un eje de retención o liberación. Negative Throttle Acelerador Negativo Normal Normal Positive Throttle Acelerador Positivo Current Value: Valor Actual: Set Set %1 Left Mouse Button Botão esquerdo do Rato Right Mouse Button Botão direito do Rato Click Clique Rigid Rigid Gradient Vibration ButtonEditDialog Dialog Janela To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Para realizar una nueva asignación, pulse cualquier tecla del teclado o haga clic en un botón en el teclado o en la pestaña ratón Placeholder marcador de posición Toggle Alternar Enables a key press or release to only occur when a controller button is pressed. Habilita la pulsación de una tecla o la liberación que sólo ocurren cuando se pulsa un botón del mando. Enables rapid key presses and releases. Turbo controller. Habilita que um botão seja pressionado rapidamente. Controle Turbo. Turbo Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Last keyboard/mouse button: Ultimo botão do Rato/Teclado: Slots Espaços Na&me: Nome: Specify the name of a button. Especifique o nome do botão. Action: Ação: Specify the action that will be performed in game while this button is being used. Especifique a ação que deverá acontecer no jogo quando este botão for pressionado. Advanced Avançado Choose your keyboard key Escolha o botão do teclado No button Nenhum botão Last button Ultimo botão To change settings for last button, it must be at least one assignment from keyboard to gamepad Para modificar as configurações do ultimo botão, ele precisa pelo menos estar associado com um controle a um botão do teclado To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad Para modificar as configurações de turbo do ultimo botão, ele precisa pelo menos estar associado com um controle a um botão do teclado No choice Nenhuma escolha Before you open window with advanced settings, you have to choice a key Antes de abrir a janela de configurações avançadas, você precisa escolher uma tecla To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Antes de abrir a janela de configurações avançadas, você precisa associar um botão do controle a uma tecla Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel X gain offset Y Start calibration Close Reset settings Save Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: Clase: TextLabel Title: Titulo: Path: Camino: Match By Properties Class Clase Title Titulo Path Camino Full Path File Name DPadContextMenu Mouse (Normal) Ratón (Normal) Mouse (Inverted Horizontal) Ratón (Horizontal Invertido) Mouse (Inverted Vertical) Ratón (Vertical Invertido) Mouse (Inverted Horizontal + Vertical) Ratón (Horizontal+Vertical Invertido) Arrows Direccionales Keys: W | A | S | D Teclas: W | A | S | D NumPad Teclado Num None Nada Standard Estándar Eight Way Ocho Vías 4 Way Cardinal 4 Vias Cardinal 4 Way Diagonal 4 Vias Diagonal Mouse Settings Configuracion de Ratón DPadEditDialog Dialog Dialogo Presets: Presets: Mouse (Normal) Ratón (Normal) Mouse (Inverted Horizontal) Ratón (Horizontal Invertido) Mouse (Inverted Vertical) Ratón (Vertical Invertido) Mouse (Inverted Horizontal + Vertical) Ratón (Horizontal+Vertical Invertido) Arrows Direccionales Keys: W | A | S | D Teclas: W | A | S | D NumPad Teclado Num None Nada Dpad Mode: Modo Dpad: &Name: &Nombre: 4 Way Cardinal 4 Vias Cardinal 4 Way Diagonal 4 Vias Diagonal DPad Delay: Retraso de Dpad: Time lapsed before a direction change is taken into effect. Tiempo transcurrido antes de un cambio de dirección se tenga en efecto. s s Specify the name of a dpad. Especificar un nombre para Dpad. Mouse Settings Configuracion de Ratón Standard Estándar Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Estándar: Dpad de 8 regiones con dos botones de dirección activa cuando el dpad está en una región diagonal. Ocho manera: Dpad de 8 regiones con cada dirección que tiene su botón dedicado propio. Sólo un botón está siempre activo en en el momento. Útil para los juegos rougelike. 4 Way cardenal: Dpad de 4 regiones con las regiones correspondientes a los puntos cardinales de la DPAD. Útil para los menús. 4 Way Diagonal: Dpad de 4 regiones con cada región que corresponde a una zona de diagonal. Eight Way Ocho Vías Set Set Set %1 Set %1 EditAllDefaultAutoProfileDialog Default Profile Perfil por Defecto Profile: Perfil: Browse Navegar Open Config Abrir Config Profile file path is invalid. La ruta de archivo de perfil es invalido. ExtraProfileSettingsDialog Extra Profile Settings Configuraciones Extra de Perfil Key Press Time: Tiempo de presionado de Tecla: 0.00 ms 0.00 ms Profile Name: Nombre del Perfil: s s GameController Game Controller Controlador de juego GameControllerDPad DPad DPad GameControllerMappingDialog Game Controller Mapping Mapeo de Controles de Juego <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Mapeo de Controles de Juego (%1) (#%2) Discard Controller Mapping? ¿Descartar Mapeo de Controlador? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. ¿Descartar Mapeo para este controlador? Si lo descarta, el controlador podrá revertirse a un mando una vez que se actualicen todos los mandos. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger Gatillo JoyAccelerometerButton Up Arriba Down Abajo Left Izquierda Right Derecha Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis Ejes JoyAxisButton Negative Negativo Positive Positivo Unknown Desconocido Button Botón JoyAxisContextMenu Mouse (Horizontal) Ratón (Horizontal) Mouse (Inverted Horizontal) Ratón (Horizontal Invertido) Mouse (Vertical) Ratón (Vertical) Mouse (Inverted Vertical) Ratón (Vertical Invertido) Arrows: Up | Down Direccionales: Arriba | Abajo Arrows: Left | Right Direccionales: Izquierda | Derecha Keys: W | S Teclas: W | S Keys: A | D Teclas: A | D NumPad: KP_8 | KP_2 Teclado Num: 8 | 2 NumPad: KP_4 | KP_6 Teclado Num: 4 | 6 None Nada Mouse Settings Configuracion de Ratón Left Mouse Button Botón Izquierdo del Ratón Right Mouse Button Botón Derecho del Ratón JoyButton Processing turbo for #%1 - %2 Procesando turbo para #%1 - %2 Finishing turbo for button #%1 - %2 Finalizando turbo para botón #%1 - %2 Distance change for button #%1 - %2 Distancia de cambio para botón #%1 - %2 Button Botón [NO KEY] [SIN TECLA] [Set %1 1W] [Set %1 1W] [Set %1 2W] [Set %1 2W] [Set %1 WH] [Set %1 WH] JoyButtonContextMenu Toggle Alternar Turbo Turbo Clear Limpiar Set Select Seleccionar Set Disabled Inhabilitado Set %1 Set %1 Set %1 1W Set %1 1W Set %1 2W Set %1 2W Set %1 WH Set %1 WH JoyButtonSlot Mouse Ratón Up Arriba Down Abajo Left Izquierda Right Derecha LB BI MB BM RB BD Pause Pausa Hold Mantener Cycle Ciclo Distance Distancia Release Soltar Mouse Mod Raton Mod Press Time Tiempo de presionado Delay Retraso Load %1 Cargar %1 Set Change %1 Cambiar Set %1 [Text] %1 [Texto] %1 [Exec] %1 [Ejec] %1 [NO KEY] [SIN TECLA] JoyControlStick Stick Palanca JoyControlStickButton Up Arriba Down Abajo Left Izquierda Right Derecha Button Botón JoyControlStickContextMenu Mouse (Normal) Ratón (Normal) Mouse (Inverted Horizontal) Ratón (Horizontal Invertido) Mouse (Inverted Vertical) Ratón (Vertical Invertido) Mouse (Inverted Horizontal + Vertical) Ratón (Horizontal+Vertical Invertido) Arrows Direccionales Keys: W | A | S | D Teclas: W | A | S | D NumPad Teclado Num None Nada Standard Estándar Eight Way Ocho Vías 4 Way Cardinal 4 Vias Cardinal 4 Way Diagonal 4 Vias Diagonal Mouse Settings Configuracion de Ratón JoyControlStickEditDialog Dialog Dialogo X: 0 0 Y: Distance: Presets: Presets: Mouse (Normal) Ratón (Normal) Mouse (Inverted Horizontal) Ratón (Horizontal Invertido) Mouse (Inverted Vertical) Ratón (Vertical Invertido) Mouse (Inverted Horizontal + Vertical) Ratón (Horizontal+Vertical Invertido) Arrows Direccionales Keys: W | A | S | D Teclas: W | A | S | D NumPad Teclado Num None Nada Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Vias Cardinal 4 Way Diagonal 4 Vias Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % % Stick Delay: Time lapsed before a direction change is taken into effect. Tiempo transcurrido antes de un cambio de dirección se tenga en efecto. s s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: No&mbre: Specify the name of an analog stick. Mouse Settings Standard Estándar Bearing: % Safe Zone: Eight Way Ocho Vías Dead Zone: Zona Muerta: Max Zone: Zona Maxima: Diagonal Range: Set Set Set %1 Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad DPad JoyDPadButton Up Arriba Down Abajo Left Izquierda Right Derecha Button Botón JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Botón JoySensorContextMenu Mouse Settings JoySensorEditDialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: Presets: Presets: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. Tiempo transcurrido antes de un cambio de dirección se tenga en efecto. s s Na&me: Specify the name of an analog sensor. Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None Mouse (Normal) Ratón (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Ratón (Horizontal+Vertical Invertido) Arrows Direccionales Keys: W | A | S | D Teclas: W | A | S | D NumPad Teclado Num JoyTabWidget <New> Battery level of controller Remove Remove configuration from recent list. Load Cargar Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Configuraciones Set 1 Set 1 Set 2 Set 2 Set 3 Set 3 Set 4 Set 4 Set 5 Set 5 Set 6 Set 6 Set 7 Set 7 Set 8 Set 8 Stick/Pad Assign Asignación de Palanca/Pad Controller Mapping Quick Set Configuración rápida Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Abrir Config Config Files (*.amgp *.xml) Archivos de Config (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Palancas Sensors DPads DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1: %2 Set %1 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Set Joystick Joystick JoystickStatusWindow Properties Propiedades Details Detalles Name: Nombre: %1 %1 Number: Numero: Axes: Ejes: Buttons: Botones: Hats: Hats: Sensors: Battery: Unknown Desconocido GUID: GUID: Game Controller: Controlador de Juego: Axes Ejes Buttons Botones Hats Hats Sensors %1 (#%2) Properties %1 (#%2) Propiedades Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None Axis %1 Ejes %1 Hat %1 Hat %1 No No Yes Si MainSettingsDialog Edit Settings Editar Configuraciones General General Controller Mappings Mapeo de controles Language Lenguaje Auto Profile Auto Perfil Mouse Ratón Advanced Avanzado Pro&file Directory: <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Especificar el directorio por defecto que el programa debe utilizar en los diálogos de archivo cuando se carga un perfil o guardar un nuevo perfil.</p></body></html> Recent Profile Count: Contaje de Perfiles Recientes: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Número de perfiles que se puede colocar en la lista de perfil reciente. 0 dará lugar a que el programa no cumplir un límite en el número de perfiles que se muestran.</p></body></html> Gamepad Poll Rate: Taza de Sondeo de Mando: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Cambiar la velocidad de sondeo que el programa utiliza para descubrir nuevos eventos de mandos. El valor predeterminado es de 10 ms. La reducción del valor de velocidad de sondeo podría causar que la aplicación usar más energía de la CPU así que por favor probar la configuración que utilice antes de usar AntimicroX desatendida. Hide main window when the main window close button is clicked instead of quitting the program. Ocultar ventana principal cuando el botón de la ventana principal es estrecha se hace clic en lugar de salir del programa. Close To Tray Cerrar para la bandeja del sistema Have Windows start AntiMicroX at system startup. Hacer que Windows inicie AntimicroX junto con el sistema. Launch At Windows Startup Iniciar junto con Windows Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Mostrar perfiles más recientes de todos los mandos como una única lista en el menú de la bandeja. predeterminados a la utilización de los submenús. Single Profile List in Tray Lista única de perfiles en la bandeja de sistema Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Hacer que el programa minimize la barra de tareas. Por defecto, el programa se minimiza en el sistema la bandeja si está disponible. Minimize to Taskbar Minimizar para la barra de tareas This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Esta opción hará que el programa para ocultar todos los botones que no tienen ranuras asignadas. La ventana de diálogo de configuración rápida tendrá que ser utilizado para que aparezca el diálogo de edición para los botones del mando. Hide Empty Buttons Ocultar Botones Vacíos When the program is launched, open the last known profile that was opened during the previous session. Cuando el programa esté en marcha, abrir el último perfil conocido que se abrió durante la sesión anterior. Auto Load Last Opened Profile Auto Cargar el ultimo perfil abierto Only show the system tray icon when the program first launches. Solamente mostrar el icono en la bandeja de sistema cuando el programa inicie por primera vez. Launch in Tray Lanzar en la bandeja del sistema Associate .amgp files with AntiMicroX in Windows Explorer. Associar ficheiros .amgp ao AntiMicroX no Windows Explorer. Associate Profiles Asociar Perfiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Show low battery notification Show empty battery notification Key Repeat Repetición de Tecla Active keys will be repeatedly pressed when this option is enabled. Las teclas activadas serán presionadas repetidamente cuando esta opción esté activada. Enable Habilitar Specifies how much time should elapse before key repeating begins. Especifica cuánto tiempo debe transcurrir antes de repetión de tecla comienza. Specifies how many times key presses will be performed per seconds. Especifica cuántas veces se llevarán a cabo las pulsaciones de teclas por segundo. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntimicroX ha sido traducido a muchos idiomas diferentes por los contribuyentes. Por defecto, el programa elegirá una traducción apropiada basada en la configuración regional de su sistema. Sin embargo, puede hacer que la carga AntimicroX una traducción diferente en función del idioma que elija en la lista siguiente.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Nada Error Warning Info info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Clase Title Titulo Program Programa Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Deshabilitar la configuración de Windows "mejorada precisión del puntero" mientras AntimicroX se está ejecutando. La desactivación "mejorada precisión del puntero" permitirá el movimiento del ratón dentro de AntimicroX a ser más preciso. Disable Enhance Pointer Precision Desactivar la precisión del puntero mejorado Smoothing suavizado Refresh Rate: Taza de Actualizacion: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. La frecuencia de actualización es la cantidad de tiempo que transcurrirá entre los eventos del ratón. Por favor tenga cuidado cuando la edición de este ajuste ya que esto haría que el programa utilice más potencia de CPU. Un valor demasiado bajo puede causar inestabilidad del sistema. Por favor, probar la configuración antes de usar sin vigilancia. Spring Spring Screen: Pantalla: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Utilizar la pantalla especificada para el modo spring. En Linux, el por defecto es el uso de la pantalla principal. En Windows, el valor por defecto es utilizar todas las pantallas disponibles. Accel Numerator: Numerador de Aceleración: 0 0 Accel Denominator: Denominador de Aceleración: Accel Threshold: Límite de Aceleración: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Si los valores de aceleración para el ratón virtual han sido cambiados por un proceso diferente, particularmente cuando se cierra un juego antiguo, entonces es posible que desee restablecer la aceleración Los valores utilizados por el ratón virtual. Reset Acceleration Resetear Aceleración Delay: Retraso: ms ms Rate: Taza: times/s tiempo/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. A continuación se muestra una lista de las asignaciones personalizados que se han guardado. Puede usar la siguiente tabla para eliminar las asignaciones o tienen asignaciones temporalmente deshabilitados. También puede desactivar las asignaciones que se incluyen con SDL; sólo tiene que insertar una nueva fila con el GUID de la palanca de mando correspondiente y vaya desactivar. Los ajustes no tendrán efecto hasta que actualizar todos los mandos o desenchufar el mando en particular. GUID GUID Mapping String Cadena de Mapeo Disable? Inhabilitar? Delete Borrar Default Por Defecto English Inglés Active Activo Devices: Dispositivos: All Todo Device Dispositivo Profile Perfil Default? Por Defecto? Add Agregar Edit Editar AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Además, los usuarios de Windows que deseen utilizar un valor bajo,pueden tambien marcarl "Desactivar el puntero de precisión" en caso de que no haya desactivado la opción en Windows. Select Default Profile Directory Seleccionar el Directorio de Perfil por defecto Are you sure you want to delete the profile? Está seguro que quiere borrar el perfil? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu Ningún Mando fue encontrado Por favor conecte un Mando y elija la opción "Actualizar Mandos" en el menu principal If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &App &Options &Opciones He&lp &Quit S&alir Ctrl+Q Ctrl+Q &Update Joysticks Act&ualizar Mandos Ctrl+U Ctrl+U &Hide O&cultar Ctrl+H Ctrl+H &About So&bre Ctrl+A Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page Home Page (%1) (%1) Open File Abrir Ficheiro Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore &Restaurar Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? ¿Ejecutar como Administrador? Failed to elevate program Fallo al elevar el programa Failed to restart this program as the Administrator Fallo al reiniciar este programa como administrador MouseAxisSettingsDialog Mouse Settings - Set %1 Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 Set %1 MouseSensorSettingsDialog Mouse Settings Set %1 Set %1 MouseSettingsDialog Mouse Settings Configuracion de Ratón Mouse Mode: Modo Ratón: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Cursor Spring Spring Acceleration: Aceleración: Enhanced Precision Puntero Mejorado Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier La aceleración comienza en este porcentaje de la base de multiplicador Minimum amount of axis travel required for acceleration to begin cantidad mínima de recorrido del eje requerido para la aceleración a comenzar Max Threshold: Límite Máximo: Maximum axis travel before acceleration has reached the multiplier value El recorrido máximo del eje antes de la aceleración ha alcanzado el valor del multiplicador E&xtra Duration: Curve: Curva: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s %n notch/s %n notches/s QKeyDisplayDialog Key Checker Verificador de Teclas <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Controlador de eventos: Native Key Value: Valor de tecla nativo: 0x00000000 0x00000000 Qt Key Value: Valor QT de Tecla: antimicro Key Value: QObject Super Menu Menu Mute Vol+ Vol- Play/Pause Play Pause Pausa Prev Next Mail Home Media Media Search Buscar Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button Ultimo botão There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Localización de Perfil %1 no es un archivo XML válido. Profile location %1 does not exist. Localización de Perfil %1 No existe. Controller identifier is not a valid value. An invalid set number '%1' was specified. Un numero de Set inválido '%1' fué especificado. Controller identifier '%s'' is not a valid value. Controlador idendificado '%s'' no es un valor válido (valga la redundancia). No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. La versión xinput debe ser al menos 2,0. no se producirán cambios en la aceleración del ratón. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set Configuración rápida <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>Por favor, pulse un botón o mueva un eje en %1 (<span style=" font-weight:600;">%2</span>).<br/>una ventana de diálogo aparecerá entonces<br/>permitirá crear una asignación.</p></body></html> Quick Set %1 Configuración rápida %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? La posición del acelerador para el Eje %1 ha sido cambiado ¿Le gustaría distribuir este cambio acelerador para todos los sets? SetJoystick Set %1: %2 Set %1: %2 Set %1 Set %1 SetNamesDialog Set Name Settings Set 1 Set 1 Set 2 Set 2 Set 3 Set 3 Set 4 Set 4 Set 5 Set 5 Set 6 Set 6 Set 7 Set 7 Set 8 Set 8 Name Nombre SimpleKeyGrabberButton Mouse Ratón SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Não foi possível abrir o ficheiro de aparelho uinput Por favor, verifique se tem a permissão para escrever nesse aparelho Using uinput device file %1 A usar o ficheiro de aparelho uinput %1 UInputHelper a b c d e f g h i j k l m n o p q r s s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace Tab [ [ ] ] \ \ CapsLock ; ; ' ' Enter Shift_L , , . . / / Ctrl_L Super_L Alt_L Space Alt_R Menu Menu Ctrl_R Shift_R Up Arriba Left Izquierda Down Abajo Right Derecha PrtSc Ins Del Home End PgUp PgDn NumLock * * + + KP_Enter Enter_Num KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK SCLK Pause Pausa Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] [SIN TECLA] UnixWindowInfoDialog Captured Window Properties Information About Window Class: Clase: TextLabel Title: Titulo: Path: Camino: Match By Properties Class Clase Title Titulo Path Camino VDPad VDPad VirtualKeyPushButton Space Espaciador Tab Tabulador Shift (L) Mayus (Izq) Shift (R) Mayus (Der) Ctrl (L) Ctrl (Izq) Ctrl (R) Ctrl (Der) Alt (L) Alt (Izq) Alt (R) Alt (Der) Alt Gr ` ` ~ ~ - - = = [ [ ] ] \ \ Caps Caps ; ; ' ' , , . . / / ESC ESC PRTSC PRTSC SCLK SCLK INS INS PGUP RePag DEL SUPR PGDN AvPag 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK BLOCK NUM * * + + Enter Del < < : : Super (L) Super (Izq) Menu Menu Up Arriba Down Abajo Left Izquierda Right Derecha VirtualKeyboardMouseWidget Keyboard Teclado Mouse Ratón Mouse Settings Configuraciones de Ratón Left Mouse Ratón Izquierda Up Mouse Ratón Arriba Left Button Mouse Ratón Boton Izquierdo Middle Button Mouse Ratón Boton del Medio Right Button Mouse Ratón Botón Derecho Wheel Up Mouse Ratón Rueda Arriba Wheel Left Mouse Ratón Rueda Izquierda Wheel Right Mouse Ratón Rueda Derecha Wheel Down Mouse Ratón Rueda Abajo Down Mouse Ratón Abajo Right Mouse Ratón Derecha Button 4 Mouse Ratón Botón 4 Mouse 8 Mouse Ratón Ratón 8 Button 5 Mouse Ratón Botón 5 Mouse 9 Mouse Ratón Ratón 9 NONE NADA [NO KEY] [SIN TECLA] Last button Ultimo botão Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Aplicaciones Browser Back Navegador Atrás Browser Favorites Navegador Favoritos Browser Forward Navegador Adelante Browser Home Navegador Inicio Browser Refresh Navegador Actualizar Browser Search Navegador Busca Browser Stop Navegador Parar Calc Calc Email Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Media Next Media Próximo Media Play Media Reproduzir Media Previous Media Anterior Media Stop Media Parar Search Buscar Volume Down Volume Bajar Volume Mute Volume Mudo Volume Up Volume Subir VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application Solicitación de Captura After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Después de pulsar el botón "Solicitud de captura", por favor, seleccione la ventana de la aplicación que desea tener un perfil asociado. La aplicación activa será capturado después del número de segundos seleccionado. Timer: Temporizador: Seconds Segundos Cancel Cancelar WinExtras [NO KEY] [SIN TECLA] AntiMicro Profile X11Extras ESC ESC Tab Tab Space espaciador DEL SUPR Return ENTER KP_Enter Enter_Num Backspace Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. No se ha encontrado la extensión xinput. no se producirán cambios en la aceleración del ratón. xinput version must be at least 2.0. No mouse acceleration changes will occur. La versión xinput debe ser al menos 2,0. no se producirán cambios en la aceleración del ratón. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 PeerFeedback clase no se encontró para el puntero virtual. Ningún cambio en la aceleración del ratón se producirá para el dispositivo con el id=%1 Changing mouse acceleration for device with id=%1 Cambiando la aceleración del ratón para el dispositivo con id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_pt_BR.ts000066400000000000000000014576111471077622000300040ustar00rootroot00000000000000 AboutDialog About Sobre Version Versão Info Informações Changelog Registro de alterações Credits Créditos AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originalmente desenvolvido por Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Em seguida mantido pelo grupo AntiMicro group em https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Depois por juliagoda em https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Agora mantido em https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Colaboradores:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Tradutores:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Português Brasileiro</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinês</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - Francês</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - Alemão</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - Alemão</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japonês</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russo</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Sérvia</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ucraniano</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Espanhol</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italiano</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polonês</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">LICENÇA PÚBLICA GERAL GNU</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Versão 3, 29 Junho de 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Todos estão autorizados a copiar e distribuir cópias literais deste documento de licença, mas a alteração não é permitida.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preâmbulo</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A Licença Pública Geral GNU é uma licença livre, com copyleft, para softwares e outros tipos de trabalhos. As licenças para a maioria dos softwares e outros trabalhos práticos são projetadas para tirar sua liberdade de compartilhar e alterar os trabalhos. Em contrapartida, a Licença Pública Geral GNU destina-se a garantir a sua liberdade de compartilhar e alterar todas as versões de um programa – para se certificar de que permaneça como software livre para todos os seus usuários. Nós, a Free Software Foundation, usamos a Licença Pública Geral GNU para a maioria dos nossos softwares; aplica-se também a qualquer outro trabalho divulgado desta forma pelos seus autores. Você também pode aplicá-la aos seus programas.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Quando falamos de software livre, estamos nos referindo à liberdade, não ao preço. Nossas Licenças Públicas Gerais são projetadas para garantir que você tenha a liberdade de distribuir cópias de software livre (e cobrar por elas, se desejar), que você receba o código-fonte ou possa obtê-lo, se desejar, que você possa mudar o software ou usar partes dele em novos programas livres e que você saiba que pode fazer essas coisas.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Para proteger seus direitos, precisamos impedir que outros neguem esses direitos ou peçam que você os renuncie. Portanto, você tem certas responsabilidades se você distribui cópias do software, ou se você o modifica: responsabilidades para respeitar a liberdade dos outros.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Por exemplo, se você distribuir cópias de tal programa, gratuitamente ou por uma taxa, você deve transmitir aos destinatários as mesmas liberdades que você recebeu. Você deve se certificar de que eles, também, recebam ou possam obter o código-fonte. E você deve mostrar esses termos para que eles conheçam seus direitos.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Os desenvolvedores que usam a GNU GPL protegem seus direitos com duas etapas:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) afirmam direitos autorais sobre o software e (2) oferecem-lhe esta Licença, dando permissão legal para copiá-lo, distribuí-lo e/ou modificá-lo.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Para a proteção dos desenvolvedores e dos autores, a GPL explica claramente que não há garantia para este software livre. Para o bem de tanto os usuários como os autores, a GPL exige que as versões modificadas sejam marcadas como alteradas, de modo que seus problemas não sejam atribuídos erroneamente aos autores de versões anteriores.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Alguns dispositivos são projetados para negar o acesso aos usuários para instalar ou executar versões modificadas do software dentro deles, embora o fabricante possa fazê-lo. Isso é fundamentalmente incompatível com o objetivo de proteger a liberdade dos usuários de mudar o software. O padrão sistemático de tal abuso ocorre na área de produtos para indivíduos usarem, que é precisamente onde é mais inaceitável. Portanto, nós criamos essa versão da GPL para proibir a prática desses produtos. Se esses problemas surgem substancialmente em outros domínios, estamos prontos para estender essa disposição a esses domínios em versões futuras da GPL, conforme necessário para proteger a liberdade dos usuários.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finalmente, todo programa é constantemente ameaçado por patentes de software. Os Estados não devem permitir que as patentes restrinjam o desenvolvimento e o uso de software em computadores de propósito geral, mas naqueles que o fazem, desejamos evitar o perigo especial de que as patentes aplicadas a um programa livre possam torná-lo efetivamente proprietário. Para evitar isso, a GPL se assegura que as patentes não possam ser usadas para tornar o programa não livre.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Os termos e condições precisos para a cópia, distribuição e modificação seguem abaixo.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMOS E CONDIÇÕES</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definições.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Essa Licença&quot; refere-se à versão 3 da Licença Pública Geral GNU.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; ou &quot;direitos autorais&quot;, também significa leis do tipo direito autoral que se aplicam a outros tipos de trabalhos, tal como máscaras de semicondutores.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;O Programa&quot; refere-se a qualquer trabalho com direito autoral licenciado sob esta Licença. Cada licenciado é endereçado como &quot;você&quot;. &quot;Licenciados&quot; e &quot;destinatários&quot; podem ser indivíduos ou organizações.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;Modificar&quot; um trabalho significa copiar ou adaptar tudo ou parte do trabalho de uma forma a ser necessário ter permissão de direitos autorais, além da criação de uma cópia exata. O trabalho resultante é chamado de &quot;versão modificada&quot; do trabalho anterior ou um trabalho &quot;baseado em&quot; o trabalho anterior.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Um &quot;trabalho coberto&quot; significa o Programa não modificado ou um trabalho baseado no Programa..</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;Propagar&quot; um trabalho significa fazer qualquer coisa com ele que, sem permissão, faria você direta ou secundariamente responsável por infração de acordo com a lei de direitos autorais aplicável, exceto executando-o em um computador ou modificando uma cópia privada. A propagação inclui a cópia, distribuição (com ou sem modificação), disponibilização ao público e, em alguns países, outras atividades também.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;Transmitir&quot; um trabalho significa qualquer tipo de propagação que permita a terceiros fazer ou receber cópias. A simples interação com um usuário através de uma rede de computadores, sem transferência de uma cópia, não é transmissão.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Uma interface de usuário interativa exibe &quot;Avisos Legais Apropriados&quot; na medida em que inclui um recurso conveniente e proeminentemente visível que (1) exibe um aviso de direitos autorais apropriado e (2) diz ao usuário que não há garantia para o trabalho (exceto na extensão em que as garantias são fornecidas), que os licenciados podem transmitir o trabalho sob esta Licença e como visualizar uma cópia desta Licença. Se a interface apresenta uma lista de comandos ou opções ao usuário, como um menu, um item proeminente na lista atende a este critério.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Código-fonte.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">O &quot;código-fonte&quot; para um trabalho significa a forma preferida do trabalho para fazer modificações nele. &quot;Código objeto&quot; significa qualquer forma não fonte de um trabalho.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Uma &quot;Interface Padrão&quot; significa uma interface que seja um padrão oficial definido por um corpo de padrões reconhecido ou, no caso de interfaces especificadas para uma linguagem de programação específica, que seja amplamente utilizada entre desenvolvedores que trabalham naquela linguagem.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">As &quot;Bibliotecas de Sistema&quot; de um trabalho executável incluem qualquer coisa, além do trabalho como um todo, que (a) está incluído na forma normal de empacotamento de um Componente Principal, mas que não faz parte desse Componente Principal, e (b) serve apenas para permitir o uso do trabalho com esse Componente Principal, ou para implementar uma Interface Padrão para a qual uma implementação esteja disponível ao público na forma de código-fonte. Um &quot;Componente Principal&quot;, neste contexto, significa um componente principal essencial (kernel, sistema de janelas e assim por diante) do sistema operacional específico (se houver) em que o trabalho executável é executado ou um compilador usado para produzir o trabalho, ou um interpretador de código objeto usado para executá-lo.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Fonte Correspondente&quot; para um trabalho na forma de código objeto significa todo o código-fonte necessário para gerar, instalar e (para um trabalho executável) executar o código objeto e modificar o trabalho, incluindo scripts para controlar essas atividades. No entanto, não inclui as Bibliotecas de Sistema do trabalho, nem ferramentas de uso geral ou programas livres geralmente disponíveis que são usados na forma não modificada na realização dessas atividades, mas que não fazem parte do trabalho. Por exemplo, a Fonte Correspondente inclui arquivos de definição de interface associados a arquivos fonte para o trabalho e o código-fonte para bibliotecas compartilhadas e subprogramas vinculados dinamicamente que o trabalho é projetado especificamente para exigir, como por comunicação íntima de dados ou fluxo de controle entre esses subprogramas e outras partes do trabalho.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A Fonte Correspondente não precisa incluir nada que os usuários possam regenerar automaticamente de outras partes da Fonte Correspondente..</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A Fonte Correspondente para um trabalho na forma de código-fonte é o próprio trabalho.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Permissões Básicas.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Todos os direitos concedidos sob esta Licença são concedidos para o termo de direito autoral sobre o Programa e são irrevogáveis desde que as condições estabelecidas sejam atendidas. Esta Licença afirma explicitamente a sua permissão ilimitada para executar o Programa não modificado. A saída da execução de um trabalho coberto é coberta por esta Licença somente se a saída, dado seu conteúdo, constituir um trabalho coberto. Esta Licença reconhece seus direitos de uso justo ou outro equivalente, conforme previsto pela lei de direitos autorais.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Você pode fazer, executar e propagar trabalhos cobertos que você não transmite, sem condições, desde que sua licença permaneça em vigor. Você pode transmitir trabalhos cobertos para terceiros com o único propósito de fazer com que eles façam modificações exclusivamente para você ou lhe forneçam instalações para executar esses trabalhos, desde que você cumpra os termos desta Licença transmitindo todo o material para o qual você não controla o direito autoral. Aqueles que fazem ou executam os trabalhos cobertos para você devem fazê-lo exclusivamente em seu nome, sob sua direção e controle, em termos que os impeçam de fazer cópias de seu material protegido por direito autoral fora do relacionamento deles com você.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A transmissão sob qualquer outra circunstância é permitida somente nas condições estabelecidas abaixo. Sublicenciamento não é permitido; a seção 10 o torna desnecessário.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protegendo os Direitos Legais dos Usuários contra Lei de Anti-Evasão.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nenhum trabalho coberto deve ser considerado parte de uma medida tecnológica efetiva sob qualquer lei aplicável que cumpra as obrigações previstas no artigo 11 do tratado de direitos autorais da OMPI, aprovado em 20 de dezembro de 1996, ou leis similares que proíbam ou restrinjam a evasão de tais medidas.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Quando você transmite um trabalho coberto, você renuncia a qualquer poder legal para proibir a evasão de medidas tecnológicas, na extensão em que essa evasão seja efetuada exercendo direitos sob esta Licença em relação ao trabalho coberto e você renuncia a qualquer intenção de limitar operação ou modificação do trabalho como um meio de fazer cumprir, contra os usuários do trabalho, seus os direitos legais ou de terceiros para proibir a evasão de medidas tecnológicas.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Transmitindo Cópias Literais.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Você pode transmitir cópias literais do código-fonte do Programa na medida que você o recebe, em qualquer meio, desde que você publique de forma consistente e apropriada em cada cópia um aviso de direitos autorais apropriado; mantenha intactos todos os avisos afirmando que esta Licença e quaisquer termos não permissivos adicionados de acordo com a seção 7 se aplicam ao código; mantenha intactos todos os avisos da ausência de qualquer garantia; e dê a todos os destinatários uma cópia desta Licença junto com o Programa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Você pode cobrar qualquer preço ou nenhum preço por cada cópia que você transmite, e você pode oferecer proteção de suporte ou garantia por uma taxa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Transmitindo Versões Modificadas das Fontes.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Você pode transmitir um trabalho baseado no Programa, ou as modificações para produzi-lo a partir do Programa, na forma de código-fonte sob os termos da seção 4, desde que você também atenda a todas essas condições:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) O trabalho deve levar avisos proeminentes afirmando que você o modificou e dando uma data relevante.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) O trabalho deve levar avisos proeminentes afirmando que ele está lançado sob esta Licença e quaisquer condições adicionadas sob a seção 7. Este requisito modifica o requisito na seção 4 de &quot;mantenha intactos todos os avisos&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Você deve licenciar o trabalho, como um todo, sob esta Licença para qualquer pessoa que entre na posse de uma cópia. Esta Licença, portanto, se aplicará, juntamente com todos os termos adicionais aplicáveis da seção 7, a totalidade do trabalho e todas as suas partes, independentemente de como elas são empacotadas. Esta Licença não dá permissão para licenciar o trabalho de qualquer outra forma, mas não invalida tal permissão se você o recebeu separadamente.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Se o trabalho tiver interfaces de usuário interativas, cada um deve exibir Avisos Legais Apropriados; no entanto, se o Programa tiver interfaces interativas que não exibam Avisos Legais Apropriados, seu trabalho não precisa exibi-los.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Uma compilação de um trabalho coberto com outros trabalhos separados e independentes, que não são, por sua natureza, extensões do trabalho coberto e que não estão combinados com ele de modo a formar um programa maior, em um volume de armazenamento ou meio de distribuição, é chamada de &quot;agregada&quot; se a compilação e seus direitos autorais resultantes não forem usados para limitar o acesso ou os direitos legais dos usuários da compilação além do que trabalhos individuais permitem. A inclusão de um trabalho coberto em um agregado não faz com que esta Licença se aplique às outras partes do agregado.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Transmitindo Formas Não Fonte.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Você pode transmitir um trabalho coberto na forma de código objeto nos termos das seções 4 e 5, desde que você também transmita o Fonte Correspondente legível por máquina sob os termos desta Licença, de uma dessas maneiras:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Transmitir o código objeto em, ou incorporado em, um produto físico (incluindo um meio de distribuição física), acompanhado pelo Fonte Correspondente, fixada em um meio físico durável usualmente usado para intercâmbio de software.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Transmitir o código objeto em, ou incorporado em, um produto físico (incluindo um meio de distribuição física), acompanhado de uma oferta escrita, válido por pelo menos três anos e válido enquanto você oferecer peças sobressalentes ou suporte ao cliente para aquele modelo de produto, para fornecer a qualquer pessoa que possua o código objeto (1) uma cópia do Fonte Correspondente para todo o software no produto coberto por esta Licença, em um meio físico durável usualmente usado para intercâmbio de software, por um preço não mais do que o seu custo razoável de realizar fisicamente esse envio de fonte, ou (2) acessar para copiar o Fonte Correspondente de um servidor de rede sem custo.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Transmitir cópias individuais do código objeto com uma cópia da oferta escrita para fornecer o Fonte Correspondente. Esta alternativa é permitida apenas de forma ocasional e não comercial, e somente se você recebeu o código objeto com tal oferta, de acordo com a subseção 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Transmitir o código objeto, oferecendo acesso a partir de um local designado (gratuitamente ou por uma taxa), e oferecer acesso equivalente ao Fonte Correspondente da mesma maneira através do mesmo local sem custo adicional. Você não precisa exigir que os destinatários copiem o Fonte Correspondente junto com o código objeto. Se o local para copiar o código objeto for um servidor de rede, o Fonte Correspondente pode estar em um servidor diferente (operado por você ou um terceiro) que suporte instalações de cópia equivalentes, desde que você mantenha instruções claras ao lado do código objeto, dizendo onde encontrar o Fonte Correspondente. Independentemente de qual servidor que hospeda o Fonte Correspondente, você permanece obrigado a garantir que ele esteja disponível enquanto for necessário para satisfazer esses requisitos.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Transmitir o código objeto usando a transmissão ponto a ponto, desde que você informe outros pares onde o código objeto e o Fonte Correspondente do trabalho estão sendo oferecidos ao público em geral sem cobrança nos termos da subseção 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Uma porção separável do código objeto, cujo código-fonte é excluído do Fonte Correspondente como uma Biblioteca de Sistema, não precisa ser incluída na transmissão do trabalho do código objeto.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Um &quot;Produto do Usuário&quot; é (1) um &quot;produto de consumo&quot;, o que significa que qualquer propriedade pessoal tangível que normalmente é usada para fins pessoais, familiares ou domésticos, ou (2) qualquer coisa projetada ou vendida para incorporação em uma habitação. Ao determinar se um produto é um produto de consumo, os casos duvidosos devem ser resolvidos a favor da cobertura. Para um determinado produto recebido por um determinado usuário, &quot;normalmente usado&quot; refere-se a um uso típico ou comum dessa classe de produto, independentemente do status do usuário específico ou da maneira em que o usuário particular realmente usa, ou espera ou é esperado usar, o produto. Um produto é um produto de consumo, independentemente de o produto possuir importantes usos comerciais, usos industriais ou sem ser consumidores, a menos que essas utilizações representem o único modo significativo de uso do produto.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Informações de Instalação&quot; para um Produto de Usuário significa que quaisquer métodos, procedimentos, chaves de autorização ou outras informações necessárias para instalar e executar versões modificadas de um trabalho coberto nesse Produto de Usuário de uma versão modificada de seu Fonte Correspondente. As informações devem ser suficientes para garantir que o contínuo funcionamento do código objeto modificado não seja de modo algum proibido ou interferido apenas porque a modificação foi feita.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Se você transmitir um código objeto trabalhando sob esta seção em, ou com, ou especificamente para uso em, um Produto do Usuário, e a transmissão ocorre como parte de uma transação na qual o direito de posse e uso do Produto do Usuário é transferido para o destinatário em perpetuidade ou por um termo fixo (independentemente de como a transação é caracterizada), o Fonte Correspondente transmitido sob esta seção deve ser acompanhado das Informações de Instalação. Mas este requisito não se aplica se nem você nem um terceiro tiverem a capacidade de instalar o código objeto modificado no Produto do Usuário (por exemplo, o trabalho foi instalado na ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">O requisito de fornecer Informações de Instalação não inclui um requisito para continuar a fornecer serviço de suporte, garantia ou atualizações para um trabalho que foi modificado ou instalado pelo destinatário ou para o Produto do Usuário no qual foi modificado ou instalado. O acesso a uma rede pode ser negado quando a modificação propriamente dita afeta materialmente e adversamente a operação da rede ou viola as regras e os protocolos para comunicação em toda a rede.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A Fonte Correspondente transmitida e as Informações de Instalação fornecidas, de acordo com esta seção, devem estar em um formato que esteja documentado publicamente (e com uma implementação disponível ao público na forma de código-fonte) e não deve exigir nenhuma senha ou chave especial para desempacotar, ler ou copiar.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Termos Adicionais.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Permissões adicionais&quot; são termos que complementam os termos desta Licença fazendo exceções de uma ou mais de suas condições. As permissões adicionais que são aplicáveis a todo o Programa devem ser tratadas como se estivessem incluídas nesta Licença, na extensão que elas sejam válidas de acordo com a lei aplicável. Se as permissões adicionais se aplicam apenas a parte do Programa, essa parte pode ser usada separadamente nessas permissões, mas o Programa inteiro permanece governado por esta Licença, independentemente das permissões adicionais.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Quando você transmite uma cópia de um trabalho coberto, você pode, a seu critério, remover quaisquer permissões adicionais dessa cópia ou de qualquer parte dela. (Permissões adicionais podem ser escritas para requerer sua própria remoção em certos casos quando você modifica o trabalho.) Você pode colocar permissões adicionais em material, adicionado por você a um trabalho coberto, para o qual você tenha ou possa dar permissão de direitos autorais apropriados.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Não obstante qualquer outra disposição desta Licença, para o material que você adiciona a um trabalho coberto, você pode (se autorizado pelos detentores de direitos autorais desse material) completar os termos desta Licença com os termos:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Renunciar a garantia ou limitar a responsabilidade, ao contrário dos termos das seções 15 e 16 desta Licença; ou</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Exigir a preservação de avisos legais razoáveis especificados ou atribuições de autor nesse material ou nos Avisos Legais Apropriados exibidos por trabalhos que o contenham; ou</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Proibir a falsa declaração da origem desse material, ou exigir que as versões modificadas de tais materiais sejam marcadas de maneira razoável como diferente da versão original; ou</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limitar o uso para fins publicitários de nomes de licenciadores ou autores do material; ou</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Recusar a concessão de direitos sob lei de marca registrada para o uso de alguns nomes comerciais, marcas registradas ou marcas de serviço; ou</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Exigir indenização de licenciadores e autores desse material por qualquer pessoa que transmitir o material (ou versões modificadas dele) com pressupostos contratuais de responsabilidade para o destinatário, por qualquer responsabilidade que esses pressupostos contratuais impõem diretamente aos licenciantes e autores..</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Todos os outros termos adicionais não permissivos são considerados &quot;restrições adicionais&quot; na acepção da seção 10. Se o Programa como você o recebeu, ou qualquer parte dele, contém um aviso afirmando que é regido por esta Licença, juntamente com um termo que é uma restrição adicional, você pode remover esse termo. Se um documento de licença contiver uma restrição adicional, mas permitir o relicenciamento ou transmissão sob esta Licença, você pode adicionar a um material de trabalho coberto regido pelos termos desse documento de licença, desde que a restrição adicional não sobreviva a tal relicenciamento ou transmissão.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Se você adicionar termos a um trabalho coberto de acordo com esta seção, você deve colocar, nos arquivos fonte relevantes, uma declaração dos termos adicionais que se aplicam a esses arquivos, ou um aviso indicando onde encontrar os termos aplicáveis.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termos adicionais, permissivos ou não permissivos, podem ser estabelecidos sob a forma de uma licença escrita separadamente ou estabelecidos como exceções; os requisitos acima se aplicam de qualquer maneira.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Terminação.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Você não pode propagar ou modificar um trabalho coberto, exceto conforme expressamente previsto nesta Licença. Qualquer tentativa de propagar ou modificá-la é inválida e terminará automaticamente os seus direitos sob esta Licença (incluindo quaisquer licenças de patente concedidas nos termos do terceiro parágrafo da seção 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No entanto, se você cessar toda violação desta Licença, a sua licença de um detentor de direitos autorais específicos é reintegrada (a) provisoriamente, a menos que e até que o detentor dos direitos autorais termine de forma explícita e definitiva sua licença, e (b) permanentemente, se o detentor dos direitos autorais falhar para lhe notificar da violação por algum meio razoável antes de 60 dias após a cessação.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Além disso, a sua licença de um detentor de direitos autorais específico é reintegrada de forma permanente se o detentor dos direitos autorais o notificar da violação por algum meio razoável, esta ser a primeira vez que você recebe aviso de violação desta Licença (para qualquer trabalho) desse detentor de direitos autorais, e você resolver a violação antes dos 30 dias após o recebimento do aviso.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A terminação de seus direitos sob esta seção não encerra as licenças das partes que receberam cópias ou direitos de você sob esta Licença. Se seus direitos foram encerrados e não permanentemente reintegrados, você não se qualifica para receber novas licenças para o mesmo material na seção 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Aceitação Não Exigida para Ter Cópias..</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Você não é obrigado a aceitar esta Licença para receber ou executar uma cópia do Programa. A propagação auxiliar de um trabalho coberto que ocorre apenas como consequência da utilização da transmissão ponto a ponto para receber uma cópia também não exige aceitação. No entanto, nada além dessa Licença lhe concede permissão para propagar ou modificar qualquer trabalho coberto. Essas ações infringem direitos autorais se você não aceitar esta Licença. Portanto, modificando ou propagando um trabalho coberto, você indica sua aceitação desta Licença para fazê-lo.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Licenciamento Automático de Destinatários Downstream.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Cada vez que você transmite um trabalho coberto, o destinatário recebe automaticamente uma licença dos licenciadores originais, para executar, modificar e propagar esse trabalho, sujeito a esta Licença. Você não é responsável por fazer cumprir a conformidade por terceiros com esta Licença.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Uma &quot;transação de entidade&quot; é uma transação que transfere o controle de uma organização, ou substancialmente todos os ativos de uma, ou que subdivide uma organização ou que funde organizações. Se a propagação de um trabalho coberto resultar de uma transação de entidade, cada parte para essa transação que recebe uma cópia do trabalho também recebe quaisquer licenças para o trabalho que o antecessor da parte de interesse tenha ou possa dar sob o parágrafo anterior, além de um direito à posse do Fonte Correspondente do trabalho do antecessor em interesse, se o antecessor o tiver ou possa obtê-lo com esforços razoáveis.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Você não pode impor restrições adicionais sobre o exercício dos direitos concedidos ou afirmados sob esta Licença. Por exemplo, você não pode impor uma taxa de licença, royalties ou outra cobrança pelo exercício de direitos concedidos sob esta Licença e você não pode iniciar litígio (incluindo uma ação de regresso ou reconvenção em um processo judicial) alegando que qualquer reivindicação de patente é infringida fazendo, usando, vendendo, oferecendo para venda, ou importando o Programa ou qualquer parte dele.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patentes.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Um &quot;contribuidor&quot; é um detentor de direitos autorais que autoriza o uso sob esta Licença do Programa ou um trabalho no qual o Programa se baseia. O trabalho assim licenciado é chamado de &quot;versão de contribuidor&quot; do contribuidor.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Os &quot;pedidos de patente essenciais&quot; de um contribuidor são todos os pedidos de patentes pertencentes ou controlados pelo contribuidor, já adquiridos ou adquiridos posteriormente, que seriam violados de alguma forma, permitidos por esta Licença, de fazer, usar ou vender sua versão do contribuidor, mas não inclui alegações que só seriam violadas como consequência de uma nova modificação da versão do contribuidor. Para efeitos desta definição, o &quot;controle&quot; inclui o direito de conceder sublicenças de patentes de forma consistente com os requisitos desta Licença.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Cada contribuidor concede-lhe uma licença de patente não exclusiva, mundial, livre de royalties sob os principais pedidos de patente do contribuidor, para fazer, usar, vender, oferecer para venda, importar e executar de outra forma, modificar e propagar o conteúdo da sua versão do contribuidor.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nos três parágrafos seguintes, uma &quot;licença de patente&quot; é qualquer acordo ou compromisso expresso, no entanto, denominado, para não impor uma patente (como uma permissão expressa para praticar uma patente ou convênio para não processar por violação de patente). Para &quot;conceder&quot; essa licença de patente a uma parte significa fazer tal acordo ou compromisso de não fazer valer uma patente contra a parte.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Se você transmitir um trabalho coberto, confiando sabidamente em uma licença de patente, e o Fonte Correspondente do trabalho não estiver disponível para que qualquer pessoa copie, gratuitamente e sob os termos desta Licença, através de um servidor de rede acessível ao público ou outro meio facilmente acessível, então você deve (1) fazer com que o Fonte Correspondente esteja disponível, ou (2) providenciar para se privar do benefício da licença de patente para este trabalho específico, ou (3) providenciar, de forma consistente com os requisitos desta Licença, a ampliação a licença de patente para destinatários downstream. &quot;Confiando sabidamente&quot; significa que você tem conhecimento real de que, exceto pela licença de patente, a sua transmissão do trabalho coberto em um país, ou o uso do trabalho coberto por seu destinatário em um país, violaria uma ou mais patentes identificáveis nesse país que você tem motivos para acreditar serem válidos.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Se, de acordo com ou em conexão com uma única transação ou arranjo, você transmite, ou propaga através da aquisição de um trabalho coberto e concede uma licença de patente a algumas das partes que recebem o trabalho coberto autorizando-os a usar, propagar, modificar ou transmitir uma cópia específica do trabalho coberto, a licença de patente que você concede é automaticamente estendida a todos os destinatários do trabalho coberto e trabalhos baseados nele.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Uma licença de patente é &quot;discriminatória&quot; se não incluir dentro do escopo de sua cobertura, proíbe o exercício ou está condicionada ao não exercício de um ou mais dos direitos especificamente concedidos sob esta Licença. Você não pode transmitir um trabalho coberto se você é parte de um acordo com um terceiro que está no negócio de distribuição de software, sob o qual você efetua o pagamento ao terceiro com base na extensão de sua atividade de transmissão do trabalho e sob a qual o terceiro concede, a qualquer das partes que receberiam o trabalho coberto de você, uma licença de patente discriminatória (a) em conexão com cópias do trabalho coberto transmitido por você (ou cópias feitas com essas cópias) ou (b) principalmente para e em conexão com produtos específicos ou compilações que contenham o trabalho coberto, a menos que você tenha assinado esse acordo, ou que a licença de patente tenha sido concedida, antes de 28 de março de 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nada nesta Licença deve ser interpretado como excluindo ou limitando qualquer licença implícita ou outras defesas a uma infração que de outra forma pode estar disponível para você de acordo com a lei de patentes aplicável.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. Não Entregar a Liberdade dos Outros.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Se as condições que forem impostas a você (seja por ordem judicial, acordo ou de outra forma) contradizem as condições desta Licença, elas não lhe eximem das condições desta Licença. Se você não pode transmitir um trabalho coberto para satisfazer simultaneamente suas obrigações sob esta Licença e quaisquer outras obrigações pertinentes, então, como consequência, você não pode transmitir isso. Por exemplo, se você concordar com termos que obrigam você a colecionar um royalty para transmitir ainda daqueles a quem você transmite o Programa, a única maneira de satisfazer esses termos e esta Licença seria abster-se de transmitir o Programa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Uso com a Licença Pública Geral Affero GNU.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Não obstante qualquer outra disposição desta Licença, você tem permissão para vincular ou combinar qualquer trabalho coberto com um trabalho licenciado sob a versão 3 da Licença Pública Geral Affero GNU em um único trabalho combinado e transmitir o trabalho resultante. Os termos desta Licença continuarão a se aplicar à parte que é o trabalho coberto, mas os requisitos especiais da Licença Pública Geral Affero GNU, seção 13, referentes à interação através de uma rede, serão aplicados à combinação como tal.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Versões Revisadas desta Licença.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A Free Software Foundation pode publicar versões periódicas e/ou novas da Licença Pública Geral GNU de tempos em tempos. Essas novas versões serão semelhantes em espírito à versão atual, mas podem diferir em detalhes para resolver novos problemas ou preocupações.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Cada versão recebe um número de versão distinto. Se o Programa especificar que uma certa versão numerada da Licença Pública Geral GNU &quot;ou qualquer versão posterior&quot; se aplica a ele, você tem a opção de seguir os termos e condições dessa versão numerada ou de qualquer versão posterior publicada pela Free Software Foundation. Se o Programa não especificar um número de versão da Licença Pública Geral GNU, você pode escolher qualquer versão publicada pela Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Se o Programa especifica que um intermediário pode decidir quais versões futuras da Licença Pública Geral GNU podem ser usadas, a declaração pública do intermediário de aceitação de uma versão lhe autoriza permanentemente a escolher essa versão para o Programa.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Versões posteriores da licença podem lhe dar permissões adicionais ou diferentes. No entanto, nenhuma obrigação adicional é imposta a qualquer autor ou detentor de direitos autorais como resultado de sua escolha de seguir uma versão posterior.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Aviso Legal de Garantia.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">NÃO HÁ NENHUMA GARANTIA PARA O PROGRAMA, NA EXTENSÃO PERMITIDA PELA LEI APLICÁVEL. EXCETO QUANDO TUDO INDICADO POR ESCRITO, OS DETENTORES DE DIREITOS AUTORAIS E/OU OUTRAS PARTES FORNECEM O PROGRAMA &quot;COMO ESTÁ&quot; SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO A, GARANTIAS IMPLÍCITAS DE COMERCIALIZAÇÃO E ADEQUAÇÃO PARA UM FIM ESPECÍFICO. TODO O RISCO SOBRE A QUALIDADE E O DESEMPENHO DO PROGRAMA ESTÁ COM VOCÊ. SE O PROGRAMA APRESENTAR DEFEITO, VOCÊ ASSUME O CUSTO DE TODA A MANUTENÇÃO, REPARAÇÃO OU CORREÇÃO NECESSÁRIA.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitação de Responsabilidade.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">EM NENHUM CASO, A MENOS QUE EXIGIDO PELA LEI APLICÁVEL OU ACORDADO POR ESCRITO, QUALQUER DETENTOR DE DIREITOS AUTORAIS, OU QUALQUER OUTRA PARTE QUE MODIFICA E/OU TRANSMITE O PROGRAMA COMO PERMITIDO ACIMA, SE RESPONSABILIZARÁ POR DANOS, INCLUINDO QUALQUER DANO GERAL, ESPECIAL, INCIDENTAL OU CONSEQUENCIAL QUE SURGIR DO USO OU INCAPACIDADE DE USAR O PROGRAMA (INCLUINDO, MAS NÃO SE LIMITANDO À PERDA DE DADOS OU DADOS QUE SÃO PRESTADOS IMPRECISAMENTE OU PERDAS SUSTENTADAS POR VOCÊ OU TERCEIROS OU UMA FALHA DO PROGRAMA A OPERAR COM OUTROS PROGRAMAS), MESMO SE TAL DETENTOR OU OUTRA PARTE TENHA SIDO AVISADO DA POSSIBILIDADE DE TAIS DANOS.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretação das Seções 15 e 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Se a renúncia de garantia e a limitação de responsabilidade previstos acima não puderem ter efeito legal local de acordo com seus termos, os tribunais revisionais aplicarão a lei local que se aproxima mais de uma renúncia absoluta a toda a responsabilidade civil em conexão com o Programa, a menos que uma garantia ou suposição de responsabilidade acompanhe uma cópia do Programa em troca de uma taxa.</span></p></body></html> About Development Sobre o desenvolvimento "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Copyright: 2013 - 2022 License Licença Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 Usando Manipulador de Eventos: %1 AddEditAutoProfileDialog Auto Profile Dialog Perfil Automático da Caixa de Diálogo Pro&file: Per&fil: Browse Procurar Window: Janela: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Selecionar Janela. Clique na janela do aplicativo apropriado e o caminho do arquivo do aplicativo será preenchido no formulário. Detect Window Properties Detectar Propriedades da Janela &Class: &Classe: T&itle: T&ítulo: set partial title definir título parcial Application: Aplicativo: Select Selecionar De&vices: Di&spositivos: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Selecione esse perfil para ser o padrão carregado para o dispositivo especificado. A seleção será usada em vez da opção de perfil completamente padrão. Set as Default for Controller Definir como Padrão para o Controle A different profile is already selected as the default for this device. Um perfil diferente já está selecionado como padrão para esse dispositivo. Current (%1) Atual (%1) Open Config Abrir Configurações Select Program Selecionar Programa Programs (*.exe) Programas (*.exe) Please use the main default profile selection. Por favor, use a seleção de perfil padrão principal. Main Profile Perfil Principal Already selected Já selecionado Chosen Profile Perfil Escolhido The selection will be used instead of the all default profile option. A seleção será usada em vez da opção de perfil completamente padrão. Please select a window by using the mouse. Press Escape if you want to cancel. Por favor selecione uma janela usando o mouse. Pressione Esc se você deseja cancelar. Capture Application Window Capturar a Janela do Aplicativo Could not obtain information for the selected window. Não foi possível obter informações para a janela selecionada. Application Capture Failed A Captura do Aplicativo Falhou Profile file path is invalid. Caminho do perfil é inválido. No window matching property was specified. Nenhuma propriedade de correspondência de janela foi especificada. Program path is invalid or not executable. Caminho do programa é inválido ou não executável. File is not an .exe file. Arquivo não é um .exe. No window matching property was selected. Nenhuma propriedade de correspondência de janela foi selecionada. AdvanceButtonDialog Advanced Avançado Assignments Atribuições Toggle Alternar Turbo Turbo Set Selector Definir Seletor Blank or KB/M Em Branco ou Teclado/Mouse Hold Segurar Pause Pausar Cycle Ciclo Distance Distância Insert Inserir Delete Deletar Clear All Limpar tudo Time: Tempo: 0.01s 0,01s 0s 0s Insert a pause that occurs in between key presses. Inserir uma pausa que ocorre entre pressionamentos de teclas. Release Liberar Insert a new blank slot. Inserir um novo slot vazio. Delete a slot. Deletar um slot. Clear all currently assigned slots. Limpar todos os slots atribuídos atualmente. Specify the duration of an inserted Pause or Hold slot. Especificar a duração de um slot de Pausa ou Espera inserido. 0m 0m &Mouse Speed Mod: &Mod de Velocidade do Mouse: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: Distância: % % Mouse Mod Modificação de mouse Press Time Delay Atraso Execute Executar Load Carregar Set Change Definir mudança Text Entry Texto de entrada Join Entrar Split Placeholder Marcador de posição 0 0 Set the percentage that mouse speeds will be modified by. Define a porcentagem que as velocidades do mouse serão modificadas por. Auto Reset Cycle After seconds segundos Executable: Executável: ... ... Arguments: Argumentos: Enabled Permitido Mode: Modo: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Normal Gradient Gradiente Pulse Pulso Delay: Atraso: 0.10s 0.10s Rate: Avaliar: 10.0/s 10.0/s Disabled Desativado Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] sec. seg. /sec. /seg. Not checked slots Não há espaços checados To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Espaço atual desconhecido Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: Y Axis: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Down: Left: Right: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Name: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Dead Zone: Max Zone: [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Last keyboard/mouse button: Slots Na&me: Specify the name of a button. Action: Specify the action that will be performed in game while this button is being used. Advanced Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel X gain offset Y Start calibration Close Reset settings Save Calibration Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAxis Axis JoyAxisButton Negative Positive Unknown Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Up Down Left Right LB MB RB Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] JoyControlStick Stick JoyControlStickButton Up Down Left Right Button JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: 0 Y: Distance: Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Na&me: Name: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Down Left Right Button JoyTabWidget <New> Remove Remove configuration from recent list. Load Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Details Name: %1 Number: Axes: Buttons: Hats: Battery: Unknown GUID: Game Controller: Axes Buttons Hats %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Axis %1 Hat %1 No Yes MainSettingsDialog Edit Settings General Controller Mappings Language Auto Profile Mouse Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Pro&file Directory: Show low battery notification Show empty battery notification Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID Mapping String Disable? Delete Default English Active Devices: All Device Profile Default? Add Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu Nenhum controle foi encontrado. Conecte um controle e escolha a opção "Atualizar controles" no menu principal If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Aplicativo &Options &Opções He&lp A&juda &Quit &Sair Ctrl+Q Ctrl+Q &Update Joysticks At&ualizar controles Ctrl+U Ctrl+U &Hide O&cultar Ctrl+H Ctrl+H &About Ctrl+A Ctrl+A About &Qt Sobre o &Qt Ctrl+T Ctrl+T &Properties Ctrl+P Ctrl+P &Key Checker Verificador de &teclas Ctrl+K Ctrl+K &GitHub Page Ctrl+G Ctrl+G &Game Controller Mapping Ctrl+M Ctrl+M S&ettings Ctrl+S Ctrl+S &Stick/Pad Assign Ctrl+X Ctrl+X &Wiki &Wiki Ctrl+W Ctrl+W &Issues Ctrl+I Ctrl+I &Calibration Ctrl+C Ctrl+C Home Page (%1) Open File Abrir arquivo Calibration is not available. A calibração não está disponível. Selected device doesn't have any joystick to calibrate. O dispositivo selecionado não tem nenhum controle para calibrar. Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Failed to elevate program Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Prev Next Mail Home Media Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Index: %1 UniqueID: %1 GUID: %1 VendorID: %1 ProductID: %1 Product Version: %1 Name: %1 Yes No Game Controller: %1 # of Axes: %1 # of Buttons: %1 # of Hats: %1 Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Active window changed to: Title = "%1", Class = "%2", Program = "%3" or "%4". Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. Auto-switching to profile "%1". Auto-switching to nullptr profile! xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name SimpleKeyGrabberButton Mouse SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 2 3 4 5 6 7 8 9 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK * + Enter Del < : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard Mouse Mouse Settings Left Mouse Up Mouse Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel WinExtras [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_ru.ts000066400000000000000000017730401471077622000274210ustar00rootroot00000000000000 AboutDialog About О программе Version Версия Info Информация Changelog Список изменений Credits Авторы AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Проект начат Тревисом Никлсом &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Разработка продолжена группой AntiMicro в https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">После того juliagoda по адресу https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">А сейчас дорабатывается в https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Разработчики:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Переводчики:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Португальский (Бразилия)</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Китайский</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - Французский</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - Немецкий</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - Немецкий</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Японский</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Русский</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Сербский</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Украинский</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Испанский</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Итальянский</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Польский</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:14pt; font-weight: bold;">ГЕНЕРАЛЬНАЯ ПУБЛИЧНАЯ ЛИЦЕНЗИЯ GNU.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:12pt; font-weight: bold;">Версия 3, 29 июня 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Автрские права (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Разрешается свободно копировать и распространять текст настоящей Лицензии, запрещается вносить в него изменения.</span><br /><br /></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:12pt; font-weight: bold;">Введение</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Генеральная публичная лицензия GNU (GNU GPL) - свободная лицензия для программного обеспечения и произведений других видов, разрешающая свободное создание производных произведений, используемых на условиях GNU GPL. Лицензии на большинство программ и других прикладных работ составлены так, чтобы лишить Вас права распространять и изменять такие произведения. В противоположность этому, Генеральная публичная лицензия GNU предназначена для того, чтобы предоставить Вам право распространять и изменять все версии программы, чтобы она оставалась свободным программным обеспечением для всех пользователей. Мы, Фонд свободного программного обеспечения, используем Генеральную публичную лицензию GNU для большей части нашего программного обеспечения; это относится и к другим произведениям, авторы которых сделали то же самое. Вы также можете применить ее к своим программам.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Когда мы говорим о свободном программном обеспечении, мы имеем в виду свободу использования, а не бесплатность. Наши Генеральные публичные лицензии составлены для того, чтобы убедиться, что у Вас есть право распространять копии свободного ПО (и взимать плату за них, если Вы хотите), что Вы получаете исходные тексты или можете получить их, если захотите, что Вы можете изменять программное обеспечение или использовать его части в новых свободных программах, и Вы знаете о своем праве делать все это.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Чтобы защитить Ваши права, нам нужно запретить другим отрицать их или просить Вас отказаться от них. Таким образом, если Вы распространяете копии программного обеспечения или изменяете его, у Вас появляются определенные обязанности: Вы должны уважать свободу других.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Например, если Вы распространяете копии такой программы, будь то бесплатно или за вознаграждение, Вы должны передать получателям те же права, которые получили. Вы должны убедиться, что они также получили или могут получить исходный текст. Также Вы должны ознакомить их с этими условиями, чтобы они знали свои права.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Разработчики, использующие GNU GPL, защищают Ваши права при помощи следующих мер:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) закрепляют авторское право на программное обеспечение, и (2) предлагают Вам принять условия настоящей Лицензии, закрепляющей Ваше право на создание копий, распространение и (или) внесение изменений в программное обеспечение.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Для защиты разработчиков и авторов GPL в явной форме говорит об отсутствии гарантий на свободное программное обеспечение. В интересах и пользователей и авторов GPL требует, чтобы к измененным версиям прилагалось описание изменений, так чтобы связанные с ними проблемы не могли быть ошибочно приписаны авторам предыдущих версий.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Некоторые устройства спроектированы так, чтобы запретить пользователям установку или запуск на них измененных версий программного обеспечения, разрешив это только производителю. Это в корне несовместимо с целью защиты права пользователей на изменение программного обеспечения. Как правило, такие злоупотребления происходят в области потребительских продуктов, то есть там, где это особенно неприемлемо. Поэтому мы разработали эту редакцию GPL, чтобы пресечь подобную практику в этой сфере. Если подобные проблемы возникнут в других сферах, мы готовы расширить эти положения на них в будущих редакциях GPL, настолько, насколько это нужно для того, чтобы защитить свободу пользователей.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">И наконец, каждой программе постоянно угрожают патенты на программное обеспечение. Государства не должны допускать ограничения патентами разработки и использования программного обеспечения на компьютерах общего назначения, однако, поскольку они это допускают, мы хотели бы избежать еще одной опасности, состоящей в том, что в результате патентования решений, используемых в свободной программе, она перестанет удовлетворять критериям свободного программного обеспечения. Чтобы предотвратить это, GPL гарантирует, что патентование не может быть использовано для того, чтобы сделать программу несвободной.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Детальные определения используемых терминов и описание условий копирования, распространения и внесения изменений приведены ниже.</span><br /><br /></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:12pt; font-weight: bold;">ТЕРМИНЫ И УСЛОВИЯ</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">0. Определения.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Настоящая Лицензия&quot; редакция 3 Генеральной публичной лицензии GNU.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Под &quot;Авторским правом&quot; также понимаются законы, сходные с авторско-правовыми, которые применяются к другим видам работ, например, к топологиям микросхем.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Термином &quot;Программа&quot; обозначается любое охраноспособное произведение, используемое в соответствии с настоящей Лицензией. Лицензиат именуется &quot;Вы&quot;. &quot;Лицензиаты&quot; и &quot;получатели&quot; могут быть как физическими лицами, так и организациями.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Внесение изменений&quot; в произведение означает копирование или адаптацию произведения целиком или в части, способом, требующим разрешения правообладателя, за исключением изготовления его точной копии. Получившееся в результате произведение называется &quot;измененной версией&quot; предыдущего произведения или произведением, &quot;основанным на&quot; более ранней работе.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Термином &quot;Лицензионное произведение&quot; обозначается неизмененная Программа или произведение, основанное на Программе.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Распространение&quot; произведения означает совершение с ним действий, которые при отсутствии разрешения сделают Вас прямо или косвенно ответственным за нарушение действующего закона об авторском праве, за исключением запуска на компьютере или изменения копии, созданной в личных целях. Распространение включает в себя копирование, раздачу копий (с изменениями или без них), доведение до всеобщего сведения, а в некоторых странах - и другие действия.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Передача&quot; роизведения означает любой вид распространения, который позволяет другим лицам создавать или получать копии произведения. Обычное взаимодействие с пользователем через компьютерную сеть без создания копии передачей не является.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">В диалоговом режиме пользователю должна быть показана &quot;Информация об авторском праве&quot;, достаточная для того, чтобы (1) обеспечить отображение соответствующего уведомления об авторских правах и (2) сообщить пользователю о том, что ему не предоставляется никакой гарантии на произведение (за исключением фактически предоставленных гарантий), о том, что лицензиаты могут передавать произведение на условиях, описанных в настоящей Лицензии, а также о том, как ознакомиться с текстом настоящей Лицензии. Если интерфейс предоставляет собой список пользовательских команд или настроек, наподобие меню, это требование считается выполненным при наличии явно выделенного пункта в таком меню.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">1. Исходный текст.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Под &quot;Исходным текстом&quot; понимается произведение в форме, которая более всего подходит для внесения в него изменений. &quot;Объектным кодом&quot; называется произведение в любой иной форме.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Стандартный интерфейс&quot; - интерфейс, который либо является общепринятым стандартом, введенным общепризнанным органом по стандартизации, либо, в случае интерфейсов, характерных для конкретного языка программирования - тот, который широко используется разработчиками, пишущими программы на этом языке.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Системные библиотеки&quot; исполняемого произведения включают в себя то, что не относится к произведению в целом и при этом (a) входит в обычный комплект Основного компонента, но при этом не является его частью и (b) служит только для обеспечения работы с этим Основным компонентом или реализации Стандартного интерфейса, для которого существует общедоступная реализация, опубликованная в виде исходного текста. &quot;Основным компонентом&quot; в данном контексте назван главный существенный компонент (ядро, оконная система и т.д.) определенной операционной системы (если она используется), под управлением которой функционирует исполняемое произведение, либо компилятор, используемый для создания произведения или интерпретатор объектного кода, используемый для его запуска.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Полный исходный текст&quot; для произведения в форме объектного кода - весь исходный текст, необходимый для создания, установки и (для исполняемого произведения) функционирования объектного кода, а также модификации произведения, включая сценарии, контролирующие эти действия. Однако он не включает в себя Системные библиотеки, необходимые для функционирования произведения, инструменты общего назначения или общедоступные свободные программы, которые используются в неизменном виде для выполнения этих действий, но не являются частью произведения. Полный исходный текст включает в себя, например, файлы описания интерфейса, прилагаемые к файлам исходного текста произведения, а также исходные тексты общих библиотек и динамически связанных подпрограмм, которые требуются для функционирования произведения, например для прямой передачи данных или передачи управления потоками между этими подпрограммами и другими частями произведения.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Полный исходный текст не включает в себя то, что пользователи могут получить автоматически из других частей Полного исходного текста.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Полным исходным текстом для произведения в форме исходных текстов является само это произведение.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">2. Основные права.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Все права, предоставленные на основании настоящей Лицензии, действуют в течение срока действия авторских прав на Программу и не могут быть отозваны при условии, что сформулированные в ней условия соблюдены. Настоящая Лицензия однозначно подтверждает Ваши неограниченные права на запуск неизмененной Программы. Результаты функционирования Лицензионного произведения распространяются на условиях настоящей Лицензии в случае, если они, учитывая их содержание, являются частью Лицензионного произведения. Настоящая Лицензия подтверждает Ваши права на свободное использование произведения или другие аналогичные полномочия, предусмотренные действующим законодательством об авторском праве.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Если Вы не осуществляете обычную передачу Лицензионного произведения, то можете как угодно создавать, запускать и распространять его копии до тех пор, пока Лицензия сохраняет силу. Вы можете передавать Лицензионные произведения третьим лицам исключительно для того, чтобы они внесли в них изменения для Вас или предоставили Вам возможность их запуска, при условии, что Вы соглашаетесь с условиями настоящей Лицензии при передаче всех материалов, авторскими правами на которые Вы не обладаете. Лица, создающие или запускающие Лицензионные произведения для Вас, должны делать это исключительно от Вашего имени, под Вашим руководством и контролем, на условиях, которые запрещают им создание без Вашей санкции каких-либо копий материалов, на которые Вы обладаете авторским правом.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Любая другая передача разрешается исключительно при соблюдении описанных ниже условий. Сублицензирование не допускается; раздел 10 делает его не нужным.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">3. Защита прав пользователей от законов, запрещающих обход технических средств.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Ни одно Лицензионное произведение не должно считаться содержащим эффективные технические средства, удовлетворяющие требованиям любого действующего закона, принятого во исполнение обязательств, предусмотренных статьей 11 Договора ВОИС по авторскому праву от 20 декабря 1996 года или аналогичных законов, запрещающих или ограничивающих обход таких технических средств.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">При передаче Лицензионного произведения Вы отказываетесь от всех предоставляемых законом полномочий по запрету обхода технических средств, используемых авторами в связи с осуществлением их прав, признавая, что такой обход находится в рамках осуществления прав на использование Лицензионного произведения, предоставленных настоящей Лицензией; также Вы отказываетесь от любых попыток ограничить функционирование произведения или внесение в него изменений, направленных на реализацию предоставленных Вам законом прав на запрет пользователю обхода технических средств.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">4. Передача не измененных копий.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Вы можете передавать точные копии исходных текстов Программы в том виде, в котором Вы их получили, на любом носителе, при условии, что Вы прилагаете к каждой копии соответствующее уведомление об авторских правах способом, обеспечивающим ознакомление с ним пользователя; сохраняете все уведомления о том, что к тексту применима настоящая Лицензия и любые ограничения, добавленные в соответствии с разделом 7; сохраняете все уведомления об отсутствии каких-либо гарантий; предоставляете всем получателям вместе с Программой копию настоящей Лицензии.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Вы можете установить любую цену за каждую копию, которую Вы передаете, или распространять копии бесплатно; также Вы можете предложить поддержку или гарантию за отдельную плату.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">5. Передача измененных исходных текстов.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Вы можете передавать исходный текст произведения, основанного на Программе, или изменений, необходимых для того, чтобы получить его из Программы, на условиях, описанных в разделе 4, при соблюдении следующих условий:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">а) Произведение должно содержать уведомления о произведенных Вами изменениях с указанием их даты, сделанные способом, обеспечивающим ознакомление с ними пользователя.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Произведение должно содержать уведомление о том, что оно распространяется на условиях настоящей Лицензии, а также об условиях, добавленных в соответствии с разделом 7, сделанное способом, обеспечивающим ознакомление с ним пользователя. Данное требование имеет приоритет над требованиями раздела 4 "оставлять нетронутыми все уведомления".</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Вы должны передать на условиях настоящей Лицензии всю работу целиком любому лицу, которое приобретает копию. Таким образом, настоящая Лицензия вместе с любыми применимыми условиями раздела 7 будет применяться к произведению в целом и всем его частям, независимо от их комплектности. Настоящая Лицензия не дает права на лицензирование произведения на любых других условиях, но это не лишает законной силы такое разрешение, если Вы получили его отдельно.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Если произведение имеет интерактивные пользовательские интерфейсы, каждый из них должен отображать Информацию об авторском праве; однако, если Программа имеет пользовательские интерфейсы, которые не отображают информацию об авторском праве, от Вашего произведения этого также не требуется.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Включение Лицензионного произведения в подборку на разделе хранения данных или на носителе, на котором распространяется произведение, вместе с другими отдельными самостоятельными произведениями, которые по своей природе не являются переработкой Лицензионного произведения и не объединены с ним, например, в программный комплекс, называется "набором", если авторские права на подборку не используются для ограничения доступа к ней или законных прав ее пользователей сверх того, что предусматривают лицензии на отдельные произведения. Включение Лицензионного произведения в набор не влечет применения положений настоящей Лицензии к остальным его частям.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">6. Передача произведения в формах, не относящихся к исходному тексту.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Вы можете передавать Лицензионное произведение в виде объектного кода в соответствии с положениями разделов 4 и 5, при условии, что Вы также передаете машиночитаемый Полный исходный текст в соответствии с условиями настоящей Лицензии, одним из следующих способов:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Передавая объектный код или содержащий его материальный продукт (включая носитель, на котором распространяется произведение), с приложением Полного исходного текста на материальном носителе, обычно используемом для обмена программным обеспечением.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Передавая объектный код или содержащий его материальный продукт (включая носитель, на котором распространяется произведение), с письменным предложением, действительным в течение не менее трех лет либо до тех пор, пока Вы предоставляете запасные части или поддержку для данного продукта, о передаче любому обладателю объектного кода (1) копии Полного исходного текста для всего программного обеспечения, содержащегося в продукте, на которое распространяется действие настоящей Лицензии, на физическом носителе, обычно используемом для обмена программным обеспечением, по цене, не превышающей разумных затрат на передачу копии, или (2) доступа к Полному исходному тексту с возможностью его копирования с сетевого сервера без взимания платы.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Передавая отдельные копии объектного кода с письменной копией предложения о предоставлении Полного исходного текста. Этот вариант допускается только в отдельных случаях при распространении без извлечения прибыли, и только если Вы получили объектный код с таким предложением в соответствии с пунктом 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Передавая объектный код посредством предоставления доступа к нему по определенному адресу (бесплатно или за дополнительную плату), и предлагая эквивалентный доступ к Полному исходному тексту таким же способом по тому же адресу без какой-либо дополнительной оплаты. От Вас не требуется принуждать получателей копировать Полный исходный текст вместе с объектным кодом. Если объектный код размещен на сетевом сервере, Полный исходный текст может находиться на другом сервере (управляемом Вами или третьим лицом), который предоставляет аналогичную возможность копирования; при этом Вы должны четко указать рядом с объектным кодом способ получения Полного исходного текста. Независимо от того, на каком сервере расположен Полный исходный текст, Вы обязаны убедиться в том, что он будет распространяться в течение времени, необходимого для соблюдения этих требований.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Передавая объектный код с использованием одноранговой (пиринговой) сети, при условии информирования других пользователей сети о том, где можно бесплатно получить объектный код и Полный исходный текст произведения способом, описанным в пункте 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Не нужно включать в передаваемый объектный код его отделимые части, исходные тексты которых не входят в состав Полного исходного текста, такие как Системные библиотеки.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Потребительский товар&quot; это либо (1) &quot;товар, предназначенный для личных нужд&quot;, под которым понимается любое материальное личное имущество, которое обычно используется для личных, семейных или домашних целей, или (2) что-либо спроектированное или продающееся для использования в жилище. При определении того, предназначен ли товар для личных нужд, сомнения должны толковаться в пользу положительного ответа на этот вопрос. Применительно к конкретному товару, &quot;обычно используется&quot; имеется в виду способ, которым данный вид товаров преимущественно или как правило используется, независимо от статуса конкретного пользователя или способа, которым конкретный пользователь использует, предполагает или будет использовать товар. Товар относится к предназначенным для личных нужд независимо от того, насколько часто он используется в коммерческой деятельности, промышленности или иной сфере, не относящейся к личным нуждам, за исключением случая, когда использование в этой сфере представляет собой единственный основной способ использования такого товара.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Информация, необходимая для установки&quot; Потребительского товара - любые методы, процедуры, сведения, необходимые для авторизации, или другая информация, необходимая для установки и запуска в Потребительском товаре измененных версий Лицензионного произведения, полученных при изменении Полного исходного текста. Данная информация должна быть достаточной для того, чтобы обеспечить возможность внесения в исходный текст изменений, не приводящих к ограничению или нарушению его дальнейшей работоспособности.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Если вместе с Потребительским товаром или специально для использования в нем Вы передаете произведение в виде объектного кода на условиях, описанных в данном разделе, и такая передача является частью сделки, по которой право владения и пользования Потребительским товаром переходит к получателю пожизненно или на определенный срок (независимо от признаков сделки), Полный исходный текст, передаваемый согласно данному разделу, должен сопровождаться Информацией, необходимой для установки. Но это требование не применяется, если ни Вы, ни какое-либо третье лицо не сохраняет за собой возможности установки измененного объектного кода на Потребительский товар (например, произведение было установлено в постоянную память).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Требование о предоставлении Информации, необходимой для установки, не включает в себя требование продолжения оказания услуг по поддержке, предоставления гарантии или обновлений для произведения, которое было изменено или установлено получателем, либо для Потребительского товара, в котором оно было изменено или на который оно было установлено. В доступе к сети может быть отказано, если само внесение изменений существенно и негативно влияет на работу сети, нарушает правила обмена данными или не поддерживает протоколы для обмена данными по сети.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Передаваемый в соответствии с данным разделом Полный исходный текст и предоставленная Информация, необходимая для установки, должны быть записаны в формате, который имеет общедоступное описание (и общедоступную реализацию, опубликованную в форме исходного текста) и не должны требовать никаких специальных паролей или ключей для распаковки, чтения или копирования.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">7. Дополнительные условия.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Дополнительными разрешениями&quot; называются условия, которые дополняют условия настоящей Лицензии, вводя исключения из одного или нескольких ее положений. Дополнительные разрешения, которые применимы ко всей Программе, должны рассматриваться как часть настоящей Лицензии, в той степени, в которой они соответствуют действующему законодательству. Если дополнительные разрешения применяются только к части Программы, эта часть может быть использована отдельно на измененных условиях, но вся Программа продолжает использоваться на условиях настоящей Лицензии без учета дополнительных разрешений.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Когда Вы передаете копию Лицензионного произведения, Вы можете по своему усмотрению исключить любые дополнительные разрешения, примененные к этой копии или к любой ее части. (Для дополнительных разрешений может быть заявлено требование об их удалении в определенных случаях, когда Вы вносите изменения в произведение.) Вы можете добавлять дополнительные разрешения к добавленным Вами в Лицензионное произведение материалам, на которые Вы обладаете авторскими правами или правом выдачи соответствующего разрешения.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Независимо от любых других положений настоящей Лицензии, Вы можете дополнить ее положения следующими условиями, относящимися к материалу, добавленному к Лицензионному произведению (если это разрешено обладателями авторских прав на материал):</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) отказом от гарантий или ограничением ответственности, отличающимися от тех, что описаны в разделах 15 и 16 настоящей Лицензии; либо</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) требованием сохранения соответствующей информации о правах или об авторстве материала, или включения ее в Информацию об авторском праве, отображаемую содержащим его произведением; либо</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) запретом на искажение информации об источнике происхождения материала или требованием того, чтобы измененные версии такого материала содержали корректную отметку об отличиях от исходной версии; либо</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) ограничением использования в целях рекламы имен лицензиаров или авторов материала; либо</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) отказом от предоставления прав на использование в качестве товарных знаков некоторых торговых наименований, товарных знаков или знаков обслуживания; либо</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) требованием от каждого, кто по договору передает материал (или его измененные версии), предоставления компенсации лицензиарам и авторам материала в виде принятия на себя любой ответственности, которую этот договор налагает на лицензиаров и авторов.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Все остальные ограничивающие дополнительные условия считаются &quot;дополнительными запретами&quot; по смыслу раздела 10. Если программа, которую Вы получили, или любая ее часть содержит уведомление о том, что наряду с настоящей Лицензией ее использование регулируется условием, относящимся к дополнительным запретам, Вы можете удалить такое условие. Если лицензия содержит дополнительный запрет, но допускает лицензирование на измененных условиях или передачу в соответствии с настоящей Лицензией, Вы можете добавить к Лицензионному произведению материал, используемый на условиях такой лицензии, в том случае, если дополнительный запрет не сохраняется при таком изменении условий лицензии или передаче.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Если Вы добавляете условия для использования Лицензионного произведения в соответствии с настоящим разделом, Вы должны поместить в соответствующих файлах исходного текста уведомление о том, что к этим файлам применяются дополнительные условия, или указание на то, как ознакомиться с соответствующими условиями.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Дополнительные разрешающие или ограничивающие условия могут быть сформулированы в виде отдельной лицензии или зафиксированы как исключения; вышеуказанные требования применяются в любом случае.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">8. Прекращение действия.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Вы не можете распространять Лицензионное произведение или вносить в него изменения на условиях, отличающихся от явно оговоренных в настоящей Лицензии. Любая попытка распространения или внесения изменений на иных условиях является ничтожной и автоматически прекращает Ваши права, полученные по настоящей Лицензии (включая лицензию на любые патенты, предоставленные согласно третьему пункту раздела 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Тем не менее если Вы прекращаете нарушение настоящей Лицензии, Ваши права, полученные от конкретного правообладателя, восстанавливаются (а) временно, до тех пор пока правообладатель явно и окончательно не прекратит действие Ваших прав, и (б) навсегда, если правообладатель не уведомит Вас о нарушении с помощью надлежащих средств в течение 60 дней после прекращения нарушений.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Кроме того, Ваши права, полученные от конкретного правообладателя, восстанавливаются навсегда, если правообладатель впервые любым подходящим способом уведомляет Вас о нарушении настоящей Лицензии на свое произведение (для любого произведения) и Вы устраняете нарушение в течение 30 дней после получения уведомления.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Прекращение Ваших прав, описанное в настоящем разделе, не прекращает действие лицензий лиц, которые получили от Вас копии произведения или права, предоставляемые настоящей Лицензией. Если Ваши права были прекращены навсегда и не восстановлены, Вы не можете вновь получить право на тот же материал на условиях, описанных в разделе 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">9. Акцепт не требуется для получения копий.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Вы не обязаны принимать условия настоящей Лицензии для того, чтобы получить или запустить копию Программы. Случайное распространение Лицензионного произведения, происходящее вследствие использования для получения его копии передачи по одноранговой (пиринговой) сети, также не требует принятия этих условий. Тем не менее только настоящая Лицензия дает Вам право распространять или изменять любое Лицензионное произведение. Если Вы не приняли условия настоящей Лицензии, такие действия будут нарушением авторского права. Поэтому изменяя или распространяя Лицензионное произведение, Вы выражаете согласие с условиями настоящей Лицензии.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">10. Автоматическое получение прав последующими получателями.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Каждый раз, когда Вы передаете Лицензионное произведение, получатель автоматически получает от его лицензиара право запускать, изменять и распространять это произведение при условии соблюдения настоящей Лицензии. Вы не несете ответственности за соблюдение третьими лицами условий настоящей Лицензии.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Реорганизацией&quot; называются действия, в результате которых передается управление организацией или значительная часть ее активов, а также происходит разделение или слияние организаций. Если распространение Лицензионного произведения является результатом реорганизации, каждая из сторон сделки, получающая копию произведения, также получает все права на произведение, которые предшествующее юридическое лицо имело или могло предоставить согласно предыдущему абзацу, а также право на владение Полным исходным текстом произведения от предшественника, осуществляемое в его интересах, если предшественник владеет им или может получить его при разумных усилиях.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Вы не можете налагать каких-либо дополнительных ограничений на осуществление прав, предоставленных или подтвержденных в соответствии с настоящей Лицензией. Например, Вы не можете ставить осуществление прав, предоставленных по настоящей Лицензии, в зависимость от оплаты отчислений, роялти или других сборов; также Вы не можете инициировать судебный процесс (включая встречный иск или заявление встречного требования в судебном процессе) о нарушении любых патентных прав при создании, использовании, продаже, предложении продажи, импорте Программы или любой ее части.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">11. Патенты.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Инвестором&quot; называется правообладатель, разрешающий использование Программы либо произведения, на котором основана Программа, на условиях настоящей Лицензии. Произведение, лицензированное таким образом, называется &quot;версией со вкладом&quot; инвестора.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Неотъемлемые патентные претензии&quot; инвестора - все патентные права, принадлежащие инвестору или контролируемые им в настоящее время либо приобретенные в будущем, которые могут быть нарушены созданием, использованием или продажей версии со вкладом, допускаемыми настоящей Лицензией; они не включают в себя права, которые будут нарушены исключительно вследствие будущих изменений версии со вкладом. Для целей данного определения под &quot;контролем&quot; понимается право выдавать патентные сублицензии способами, не нарушающими требований настоящей Лицензии.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Каждый инвестор предоставляет Вам неисключительную безвозмездную лицензию на патент, действующую во всем мире, соответствующую неотъемлемым патентным претензиям инвестора, на создание, использование, продажу, предложение для продажи, импорт, а также запуск, внесение изменений и распространение всего, что входит в состав версии со вкладом.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">В следующих трех абзацах &quot;лицензией на патент&quot; называется любое явно выраженное вовне согласие или обязательство не применять патент (например, выдача разрешения на использование запатентованного объекта или обещание не подавать в суд за нарушение патента). &quot;Выдать&quot; кому-то такую лицензию на патент означает заключить такое соглашение или обязаться не применять патент против него.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Если Вы передаете Лицензионное произведение, сознательно основываясь на лицензии на патент, в то время как Полный исходный текст произведения невозможно бесплатно скопировать с общедоступного сервера или другим не вызывающим затруднений способом, Вы должны либо (1) обеспечить возможность такого доступа к Полному исходному тексту, либо (2) отказаться от прав, предоставленных по лицензии на патент для данного произведения, либо (3) принять меры по передаче лицензии на патент последующим получателям произведения, в соответствии с требованиями настоящей Лицензии. &quot;Сознательно основываясь&quot; означает, что Вы знаете, что при отсутствии лицензии на патент передача Вами Лицензионного произведения в определенной стране или использование получателем переданного ему Вами Лицензионного произведения в этой стране нарушит один или несколько определенных патентов этой страны, срок действия которых не истек.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Если в соответствии или в связи с единичной сделкой либо соглашением Вы передаете или делаете заказ на распространение Лицензионного произведения и предоставляете определенным лицам, получающим Лицензионное произведение, лицензию на патент, разрешающую им использовать, распространять, вносить изменения или передавать конкретные экземпляры Лицензионного произведения, то права, которые Вы предоставляете по лицензии на патент, автоматически переходят ко всем получателям Лицензионного произведения и произведений, созданных на его основе.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Патентная лицензия называется &quot;дискриминирующей&quot;, если она не покрывает, запрещает осуществление или содержит в качестве условия отказ от применения одного или нескольких прав, предоставленных настоящей Лицензией. Вы не можете передавать Лицензионное произведение, если Вы являетесь участником договора с третьим лицом, осуществляющим распространение программного обеспечения, в соответствии с которым Вы делаете в пользу третьего лица выплаты, размер которых зависит от масштабов Вашей деятельности по передаче произведения, и в соответствии с которым любое третье лицо, получающее от Вас Лицензионное произведение, делает это на условиях дискриминирующей патентной лицензии (а) которая зависит от количества копий Лицензионного произведения, переданных Вами (или копий, сделанных с этих копий), или (b) которая используется преимущественно в конкретных товарах или подборках, содержащих Лицензионное произведение, или в связи с ними, в том случае, если Вы заключили данный договор или получили лицензию на патент после 28 марта 2007 года.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Ничто в настоящей Лицензии не должно толковаться как исключение или ограничение любого предполагаемого права или других способов противодействия нарушениям, которые во всем остальном могут быть доступны для Вас в соответствии с применимым патентным правом.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">12. Запрет отказывать в свободе другим.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Если на Вас наложены обязанности (будь то по решению суда, договору или иным способом), которые противоречат условиям настоящей Лицензии, это не освобождает Вас от соблюдения ее условий. Если Вы не можете передать Лицензионное произведение так, чтобы одновременно выполнять Ваши обязательства по настоящей Лицензии и любые другие относящиеся к делу обязательства, то Вы не можете передавать его вообще. Например, если Вы согласны с условием, обязывающими Вас производить сбор отчислений за дальнейшую передачу от тех, кому Вы передаете Программу, то для того, чтобы соблюсти это условие и выполнить требования настоящей Лицензии, Вы должны полностью воздержаться от передачи Программы.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">13. Использование вместе с Генеральной публичной лицензией GNU Affero.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Независимо от любых других положений настоящей Лицензии, Вам разрешается связывать или соединять любое Лицензионное произведение в единое составное произведение с произведением, лицензированным на условиях редакции 3 Генеральной публичной лицензии GNU Affero, а также передавать получившееся произведение. Условия данной Лицензии продолжат применяться к той части, которая представляет собой Лицензионное произведение, но при взаимодействии через сеть к комбинации как таковой будут применяться особые требования, содержащиеся в разделе 13 Генеральной публичной лицензии GNU Affero.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">14. Пересмотренные редакции настоящей Лицензии.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Фонд свободного программного обеспечения время от времени может публиковать пересмотренные и (или) новые редакции Генеральной публичной лицензии GNU. Они будут аналогичны по смыслу настоящей редакции, но могут отличаться от нее в деталях, направленных на решение новых проблем или регулирование новых отношений.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Каждой редакции присваивается собственный номер. Если для Программы указано, что к ней применима определенная редакция Генеральной публичной лицензии GNU &quot;или любая более поздняя редакция&quot;, у Вас есть возможность использовать термины и условия, содержащиеся в редакции с указанным номером или любой более поздней редакции, опубликованной Фондом свободного программного обеспечения. Если для Программы не указан номер редакции Генеральной публичной лицензии GNU, Вы можете выбрать любую редакцию, опубликованную Фондом свободного программного обеспечения.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Если Вы получили Программу, содержащую указание на то, что доверенное лицо правообладателя может выбирать, какую из будущих версий Генеральной публичной лицензии GNU использовать, то публичное заявление этого лица о принятии любой версии позволяет Вам выбрать эту версию для применения ее условий к Программе.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Более поздние редакции Лицензии могут дать Вам дополнительные или принципиально иные права. Тем не менее в результате Вашего выбора более поздней редакции на автора или правообладателя не возлагается никаких дополнительных обязанностей.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">15. Отказ от гарантий.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">НА ПРОГРАММУ НЕ ПРЕДОСТАВЛЯЕТСЯ НИКАКИХ ГАРАНТИЙ ЗА ИСКЛЮЧЕНИЕМ ПРЕДУСМОТРЕННЫХ ДЕЙСТВУЮЩИМ ЗАКОНОДАТЕЛЬСТВОМ. ЕСЛИ ИНОЕ НЕ УКАЗАНО В ПИСЬМЕННОЙ ФОРМЕ, ПРАВООБЛАДАТЕЛИ И (ИЛИ) ТРЕТЬИ ЛИЦА ПРЕДОСТАВЛЯЮТ ПРОГРАММУ "КАК ЕСТЬ", БЕЗ КАКИХ-ЛИБО ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ ГАРАНТИЙ, ВКЛЮЧАЯ ГАРАНТИИ ПРИГОДНОСТИ ДЛЯ КОНКРЕТНЫХ ЦЕЛЕЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. ВЕСЬ РИСК, СВЯЗАННЫЙ С КАЧЕСТВОМ И ПРОИЗВОДИТЕЛЬНОСТЬЮ ПРОГРАММЫ, ВОЗЛАГАЕТСЯ НА ВАС. ЕСЛИ В ПРОГРАММЕ БУДУТ ВЫЯВЛЕНЫ НЕДОСТАТКИ, ВЫ ПРИНИМАЕТЕ НА СЕБЯ СТОИМОСТЬ ВСЕГО НЕОБХОДИМОГО ОБСЛУЖИВАНИЯ, РЕМОНТА ИЛИ ИСПРАВЛЕНИЯ.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">16. Ограничение ответственности.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Если иное не предусмотрено действующим законодательством или соглашением сторон, заключенным в письменной форме, правообладатель или иное лицо, которое вносит изменения в Программу и (или) передает ее на условиях, сформулированных выше, не может нести ответственность перед Вами за причиненный ущерб, включая ущерб общего либо конкретного характера, причиненный случайно или являющийся следствием использования программы либо невозможности ее использования (в том числе за уничтожение или модификацию информации, либо убытки, понесенные Вами или третьими лицами, либо сбои Программы при взаимодействии с другим программным обеспечением), в том числе и в случаях, когда правообладатель или третье лицо предупреждены о возможности причинения таких убытков.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt; font-weight: bold;">17. Толкование разделов 15 и 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Если отказ от гарантии и ограничение ответственности, представленные выше, по закону не могут быть применены в соответствии с их условиями, суды, рассматривающие спор, должны применить действующий закон, который в наибольшей степени предусматривает абсолютный отказ от всей гражданской ответственности в связи с Программой, за исключением случаев, когда гарантия или принятие на себя ответственности за копию программы предоставляется за плату.</span></p><hr /> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;"><b>Перевод:</b> Павел Протасов &lt;<a href="mailto:pvphome@gmail.com">pvphome@gmail.com</a>&gt;, 2016 г.<br /><b>Составил:</b> <a href="https://github.com/AxusWizix" target="_blank">Axus Wizix</a></span></p></body></html> About Development История разработки "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. "pktiuk" (с августа 2020 г.) Я просто хочу убедиться, что это очень полезное программное обеспечение не будет заброшено, я решил продолжить поддержку этого проекта и сделать его максимально доступным. "juliagoda" (с марта 2018 г. по 2020 г.) Желая играть только в свои любимые старые игры, которые не поддерживают геймпады, я нашел этот проект (который сопоставляет клавиши клавиатуры и кнопки мыши с подключенными геймпадами в Linux) как самый правильный и последний. Но из-за плохого выбора такого приложения в Интернете и из-за того, что оно не скомпилировалось должным образом, я решил спасти проект. Однако, как только я закончил свою работу (достаточно, чтобы наслаждаться играми), я подумал о том, чтобы поделиться этим кодом с другими. Разумеется, вся информация о прошлых программистах будет сохранена. "Ryochan7" (с 30 декабря 2012 года по 2017 год), в свободное время я работаю над AntiMicro. То, что изначально начиналось как форк QJoyPad и способ научиться правильному программированию, управляемому событиями, превратилось в нечто гораздо большее, чем я изначально планировал. Хотя я провел много времени, изучая новые методы, узнавая больше о области эмуляции KB+M и проводя пятничные вечера, стуча головой о клавиатуру, в целом это был забавный и обогащающий опыт. Необходимость в этой программе возникла после того, как я использовал аналогичные программы на Windows, чтобы играть в несколько игр, которые не обеспечивали встроенную поддержку контроллера. Хотя некоторые альтернативы существовали в Linux, не было ничего, что, по моему мнению, было бы достаточно хорошим с точки зрения функциональности или внутриигрового управления, чтобы действительно наслаждаться играми, в которые я хотел играть, используя эмуляцию KB+M. QJoyPad был основной программой, которую я использовал в прошлом, хотя она сильно устарела и не предоставляла некоторых базовых функций, которые я считал необходимыми. Проект был заброшен, поскольку он не обновлялся несколько лет, поэтому я решил создать свой собственный. С тех пор я пытался выяснить, что другие программы делают правильно, а затем улучшить это. Я также обнаружил несколько изящных приемов и узнал больше о том, как встроенные элементы управления геймпада реализованы в некоторых играх, чем я когда-либо хотел знать. Хотя определенно есть области, в которых эта программа может быть улучшена, я считаю, что эта программа предлагает наилучшие возможности управления в игре для старых и некоторых новых игр, которые не поддерживают встроенный контроллер. Разработка этой программы для меня больше не является приоритетной. В основном это связано с тем, что Steam Controller довольно хорошо справляется с задачей игры на ПК по сравнению с использованием контроллера Xbox 360. Однако, похоже, что этой программе еще есть смысл существовать некоторое время. --- С 24 мая 2016 года этот проект переехал на https://github.com/AntiMicro/antimicro. Кроме того, управление проектом перешло от Travis (Ryochan7) к организации AntiMicro из-за того, что у Travis были другие интересы и приоритеты. Далее, начиная с 2018 года проект продолжил juliagoda под названием antimicroX. Позже проект снова был перенесен на https://github.com/AntiMicroX/antimicrox, а его обслуживание продолжается организацией AntiMicroX, созданная pktiuk. Copyright: 2013 - 2022 Авторские права: 2013 - 2022 License Лицензия Program Version %1 Версия программы %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Программа скомпилирована на %1 в %2 Built Against SDL %1 Собрана с SDL %1 Running With SDL %1 Запущена с SDL %1 Using Qt %1 Версия Qt %1 Using Event Handler: %1 Текущий обработчик событий: %1 AddEditAutoProfileDialog Auto Profile Dialog Автоматический профиль Pro&file: Про&филь: Browse Обзор Window: Окно: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Выбор окна. Кликните на окно желаемого приложения, и путь до исполняемого файла этого приложения автоматически подставится в форму. Detect Window Properties Определить свойства окна &Class: &Класс: T&itle: З&аголовок: set partial title Искать частичные совпадения Application: Приложение: Select Выбрать De&vices: Ус&тройства: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Выберите профиль, который будет автоматически загружаться для выбранного устройства. Выбранный профиль загрузится, даже если выбран профиль по умолчанию. Set as Default for Controller Сделать профилем по умолчанию для этого контроллера A different profile is already selected as the default for this device. Для этого устройства уже назначен другой профиль по умолчанию. Current (%1) Текущий (%1) Open Config Загрузить конфигурацию Select Program Выбрать программу Programs (*.exe) Программы (*.exe) Please use the main default profile selection. Пожалуйста, используйте основной профиль по умолчанию. Main Profile Основной профиль Already selected Уже выбран Chosen Profile Выбранный профиль The selection will be used instead of the all default profile option. Выбранное будет использоваться вместо всех настроек по умолчанию. Please select a window by using the mouse. Press Escape if you want to cancel. Пожалуйста, выберите окно при помощи мыши. Для отмены нажмите Esc. Capture Application Window Захватить окно приложения Could not obtain information for the selected window. Не удалось получить информацию о выбранном окне. Application Capture Failed Не удалось выполнить захват приложения Profile file path is invalid. Путь до профиля неверен. No window matching property was specified. Не выбраны условия поиска окна. Program path is invalid or not executable. Путь до программы неверен или не указывает на программу. File is not an .exe file. Файл не является исполняемым (.exe) файлом. No window matching property was selected. Не отмечены условия поиска окна. AdvanceButtonDialog Advanced Продвинутые настройки Assignments Назначения Toggle Переключатель Turbo Турбо Set Selector Установить селектор Blank or KB/M Оставить пустым или выбрать KB/M Hold Удерживать Pause Пауза Cycle Цикл Distance Дистанция Insert Вставить Delete Удалить Clear All Очистить всё Time: Время: 0.01s 0,01 сек 0s 0 сек Insert a pause that occurs in between key presses. Вставить паузу между нажатиями на кнопку. Release Отпускание Insert a new blank slot. Вставить новый пустой слот. Join Присоединить Split Разделить Delete a slot. Удалить слот. Clear all currently assigned slots. Очистить все заполненные слоты. Specify the duration of an inserted Pause or Hold slot. Укажите продолжительность для вставленной паузы или удержания 0m 0 мин &Mouse Speed Mod: &Модификатор скорости курсора: Specify the range past an axis dead zone in which a sequence of actions will execute. Определяет диапазон оси для мертвой зоны в котором следует выполнять действия. Distance: Дистанция: % % Mouse Mod Скорость мыши Press Time Время нажатия Delay Задержка Execute Выполнить Load Загрузить Set Change Установить изменения Text Entry Текстовое значение Placeholder Плейсхолдер 0 0 Set the percentage that mouse speeds will be modified by. Определяет в процентах, насколько должна быть изменена скорость мыши. Auto Reset Cycle After Автоматически сбросить цикл после seconds секунд Executable: Исполняемый файл: ... ... Arguments: Аргументы: Enabled Включено Mode: Режим: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>Обычный: Нажимать и отпускать клавишу в выбранном темпе.</p><p>Градиент: Изменять задержки нажатий и отпускания клавиш в зависимости от того, насколько далеко нажата ось. Темп изменяться не будет.</p><p>Пульс: Изменять темп нажатий и отпусканий клавиш. Задержки изменяться не будут.</p></body></html> Normal Обычный Gradient Градиент Pulse Пульс Delay: Задержка: 0.10s 0,10 сек Rate: Частота: 10.0/s 10,0/сек Disabled Отключено Select Set 1 One Way Установить Набор 1 Односторонним Select Set 1 Two Way Установить Набор 1 Двусторонним Select Set 1 While Held Установить Набор 1 Пока Нажато Select Set 2 One Way Установить Набор 2 Односторонним Select Set 2 Two Way Установить Набор 2 Двусторонним Select Set 2 While Held Установить Набор 2 Пока Нажато Select Set 3 One Way Установить Набор 3 Односторонним Select Set 3 Two Way Установить Набор 3 Двусторонним Select Set 3 While Held Установить Набор 3 Пока Нажато Select Set 4 One Way Установить Набор 4 Односторонним Select Set 4 Two Way Установить Набор 4 Двусторонним Select Set 4 While Held Установить Набор 4 Пока Нажато Select Set 5 One Way Установить Набор 5 Односторонним Select Set 5 Two Way Установить Набор 5 Двусторонним Select Set 5 While Held Установить Набор 5 Пока Нажато Select Set 6 One Way Установить Набор 6 Односторонним Select Set 6 Two Way Установить Набор 6 Двусторонним Select Set 6 While Held Установить Набор 6 Пока Нажато Select Set 7 One Way Установить Набор 7 Односторонним Select Set 7 Two Way Установить Набор 7 Двусторонним Select Set 7 While Held Установить Набор 7 Пока Нажато Select Set 8 One Way Установить Набор 8 Односторонним Select Set 8 Two Way Установить Набор 8 Двусторонним Select Set 8 While Held Установить Набор 8 Пока Нажато [NO KEY] [НЕ ЗАДАНО] sec. сек. /sec. /сек. Not checked slots Непроверенные слоты To delete slots, you need to select at least one Чтобы удалить слоты, вам нужно выбрать как минимум один To insert slots, you need to select at least one Чтобы вставить слоты, нужно выбрать как минимум один Unknown current slot Выбран неизвестный слот Click on chosen slots before joining them Нажмите на выбранные слоты перед их присоедением Not enough slots Недостаточно слотов It's impossible to join slots. Add at least one other slot. Невозможно присоединить слоты. Выберите как минимум ещё один. Not selected slots Ни один слот не выбран It's impossible to join slots. Select at least two slots before joining them Невозможно присоединить слоты. Выберите как минимум два слота Only keyboard slots Только слоты клавиатуры It's only possible to join simple and mix keyboard slots Возможно присоединить только простые и комплексные слоты It's impossible to split slots. Add at least one other slot. Невозможно разделить слоты. Добавьте как минимум один другой слот. Not selected slot Не выбран слот Select your slot before splitting. Выберите слот перед разделением. Too many mix slots Слишком много комплексных слотов Select one mix slot. Выберите один комплексный слот. Only mix slots Только комплексные слоты It's only possible to split mix slot. Разделить можно только комплексные слоты. Empty execution path Пустой путь к исполняемому файлу Line for execution file path is empty. Fill the first line before you are going to add a slot. Вы не выбрали ни одного пути к исполняемым файлам. Заполните хотя бы один перед добавлением слота. File doesn't exist Файл не существует There is no such file locally, that could be executed. Check the file on your system Нет такого локального файла, который можно было бы запустить. Проверьте файл на своей системе Set %1 Набор %1 Select Set %1 Установить набор %1 One Way Односторонний Two Way Двусторонний While Held Пока нажато Choose Executable Выберите исполняемый файл Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Слоты после Цикла будут выполнены на следующем нажатии кнопки. Несколько циклов могут быть использованы для создания разделов в последовательности. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Задерживает выполнение слота на выбранное время. Слоты, выполняемые до задержки, будут активны во время задержки. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Дистанция позволяет выполнять слот после неё только при определённом расстоянии оси от изначальной мёртвой зоны. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Действие удержания. Слоты после этого действия будут выполнены только если кнопка будет нажата в течении выбранного времени. Chose a profile to load when this slot is activated. Выберите профиль, который нужно загрузить, когда будет активирован этот слот. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Мод мыши будет модифицировать все настройки скорости мыши во время действия слота. Может быть полезно для замедления мыши при использовании прицела. Specify the time that keys past this slot should be held down. Определите время, которое нужно удерживать кнопки, нажатые следующими слотами. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Действие отпускания. Слоты после этого действия будут выполнены только когда нажатие будет закончено, если оно продолжалось не менее указанного времени. Change to selected set once slot is activated. Изменить выбранный набор при выполнении слота. Full string will be typed when a slot is activated. Строка будет напечатана при активации слота. Execute program when slot is activated. Программа будет включена при активации слота. Choose Profile Выберите профиль Config Files (*.amgp *.xml) Файлы конфигурации (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Настройки стиков / крестовин Sticks Стики DPads Крестовины Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. Примечание: Это окно предназначено для обратной совместимости с профилями, созданными до версии antimicro 2.0. Начиная с версии 2.0, предпочтительнее использовать окно Сопоставление игровых контроллеров. %1 (Joystick %2) %1 (Геймпад %2) Stick 1 Стик 1 Enabled Включено Assign Назначить X Axis: Ось X: Y Axis: Ось Y: Stick 2 Стик 2 Number of Physical DPads: %1 Количество физических крестовин: %1 Virtual DPad 1 Виртуальная крестовина 1 Up: Вверх: Down: Вниз: Left: Влево: Right: Вправо: Axis %1 Ось %1 Axis %1 - Ось %1 - Axis %1 + Ось %1 + Button %1 Кнопка %1 Move stick 1 along the X axis Переместите Cтик 1 по оси X Move stick 1 along the Y axis Переместите Cтик 1 по оси Y Move stick 2 along the X axis Переместите Cтик 2 по оси X Move stick 2 along the Y axis Переместите Cтик 2 по оси Y Press a button or move an axis Нажмите кнопку или подвигайте стик AxisEditDialog Axis Ось Mouse (Horizontal) Мышь (горизонталь) Mouse (Inverted Horizontal) Мышь (инвертированная горизонталь) Mouse (Vertical) Мышь (вертикаль) Mouse (Inverted Vertical) Мышь (инвертированная вертикаль) Arrows: Up | Down Стрелки: Вверх | Вниз Arrows: Left | Right Стрелки: Влево | Вправо Keys: W | S Клавиши: W | S Keys: A | D Клавиши: A | D NumPad: KP_8 | KP_2 NumPad: 8 | 2 NumPad: KP_4 | KP_6 NumPad: 4 | 6 None Отсутствует Set the value to use as the limit for an axis. Useful for a worn out analog stick. Установите значение, которое будет использоваться в качестве предельного значения для оси. Пригодится для изношенного аналогового стика. Negative Half Throttle Отрицательная Полутяга Positive Half Throttle Положительная Полутяга Haptic Trigger: Тактильный триггер: Name: Имя: Specify the name of an axis. Укажите имя для оси. Mouse Settings Настройки Мыши Set the value of the dead zone for an axis. Устанавливает значение мертвой зоны для оси. Presets: Предустановки: Dead Zone: Мертвая зона: Max Zone: Лимит: [NO KEY] [НЕ ЗАДАНО] Throttle setting that determines the behavior of how to interpret an axis hold or release. Настройки тяги определяют как программа будет расценивать удерживание или отпускание оси. Negative Throttle Отрицательная Тяга Normal Нормально Positive Throttle Положительная Тяга Current Value: Текущее значение: Set Установки для Set %1 Набор %1 Left Mouse Button Левая кнопка мыши Right Mouse Button Правая кнопка мыши Click Щелчок Rigid Жёсткий Rigid Gradient Жесткий градиент Vibration Вибрация ButtonEditDialog Dialog Окно To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Чтобы назначить новое действие, нажмите на соответствующую кнопку во вкладках "Клавиатура" или "Мышь" Placeholder Заполнитель Toggle Переключатель Enables a key press or release to only occur when a controller button is pressed. Добавляет возможность производить действие только в случае нажатия или отпускания кнопки. Enables rapid key presses and releases. Turbo controller. Добавляет возможность быстрого нажатия кнопок (как в турбо контроллере). Turbo Турбо Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Помните, что он не будет работать, если у вас нет такой клавиатуры, подключенной к компьютеру, или если она не встроена, как в настольные ПК Attach the numeric keypad Присоедините цифровую клавиатуру Last keyboard/mouse button: Последняя клавиша/кнопка мыши: Slots Слоты Na&me: &Имя: Specify the name of a button. Укажите название кнопки. Action: Действие: Specify the action that will be performed in game while this button is being used. Укажите действие, которое будет исполняться при нажатии данной кнопки. Advanced Дополнительно Choose your keyboard key Выберите клавишу No button Без кнопки Last button Последняя кнопка To change settings for last button, it must be at least one assignment from keyboard to gamepad Чтобы изменить настройки для последней кнопки, она должна быть хотя бы одной из назначений с клавиатуры на геймпад To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad Чтобы изменить настройки турбо для последней кнопки, должно быть хотя бы одно назначение с клавиатуры на геймпад No choice Без выбора Before you open window with advanced settings, you have to choice a key Прежде чем открыть окно с расширенными настройками, необходимо выбрать клавишу To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Чтобы открыть расширенный диалог, необходимо сопоставить хотя бы одну кнопку с клавиатуры на геймпад Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Слоты для кнопок не могут быть очищены, потому что не было задано ни одной кнопки с клавиатуры под геймпад. Установите хотя бы одну кнопку с клавиатуры под геймпад As last gamepad button has been set Поскольку последняя кнопка геймпада была установлена Index %1 Индекс %1 Calibration Form Форма Input to calibrate: Ввод для калибровки: Steps Шаги Z Z TextLabel Метка текста X X gain коэффициент усиления offset смещение Y Y Start calibration Откалибровать Close Закрыть Reset settings Сбросить настройки Save Сохранить Calibration Калибровка Gyroscope Гироскоп Accelerometer Акселерометр Selected device doesn't have any inputs to calibrate. Выбранное устройство нет имеет органов, нуждающихся в калибровке. Calibration was not saved for the preset. Do you really want to continue? Калибровка не была сохранена для предустановки. Вы действительно хотите продолжить? Do you really want to reset calibration of current device? Вы точно хотите сбросить калибровку для этого устройства? Accelerometer calibration sets the neutral controller orientation. Калибровка акселерометра устанавливает нейтральную ориентацию контроллера. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Калибровка гироскопа корректирует смещение датчика. Это предотвращает перемещение курсора, пока контроллер находится в состоянии покоя. Calibration completed. Калибровка завершена. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Калибровка смещения завершена. Нажмите "Продолжить калибровку" для калибровки усиления. Hold the controller in the desired neutral position and press continue. Удерживайте контроллер в нужном нейтральном положении и нажмите «Продолжить». Calibrating accelerometer Калибровка акселерометра Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Сбор данных с акселерометра... Пожалуйста, держите контроллер неподвижно. Это может занять до %1 секунды. Place the controller at rest, e.g. put it on the desk, and press continue. Поместите контроллер в состояние покоя, т.е. положите его на стол и нажмите «Продолжить». Calibrating gyroscope Калибровка гироскопа Collecting gyroscope data... This can take up to %1 seconds. Сбор данных гироскопа... Это может занять до %1 секунд. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Теперь несколько раз поводите стиком на максимум в разные стороны и вернитесь в центр. Это может занять до %1 секунд(ы). Calibrating stick Калибровка стика Continue calibration Продолжить калибровку Now move the stick in full circles for several times. This can take up to %1 seconds. Теперь несколько раз поводите стиком по всему кругу. Это может занять до %1 секунд(ы). Calibration was saved for the preset. Do you really want to reset settings? Калибровка была сохранена для предустановки. Вы действительно хотите сбросить настройки? CapturedWindowInfoDialog Captured Window Properties Свойства захваченного окна Information About Window Информация об окне Class: Класс: TextLabel Метка текста Title: Заголовок: Path: Путь: Match By Properties Сопоставление по свойствам Class Класс Title Заголовок Path Путь Full Path Полный путь File Name Имя файла DPadContextMenu Mouse (Normal) Мышь (нормально) Mouse (Inverted Horizontal) Мышь (инвертированная горизонталь) Mouse (Inverted Vertical) Мышь (инвертированная вертикаль) Mouse (Inverted Horizontal + Vertical) Мышь (инвертированная горизонталь + вертикаль) Arrows Стрелки Keys: W | A | S | D Клавиши: W | A | S | D NumPad Цифровая клавиатура None Отсутствует Standard Стандартный Eight Way Независимый 4 Way Cardinal 4-ходовой основной 4 Way Diagonal 4-ходовой диагональный Mouse Settings Настройки мыши DPadEditDialog Dialog Окно Presets: Предустановки: Mouse (Normal) Мышь (нормально) Mouse (Inverted Horizontal) Мышь (инвертированная горизонталь) Mouse (Inverted Vertical) Мышь (инвертированная вертикаль) Mouse (Inverted Horizontal + Vertical) Мышь (инвертированная горизонталь + вертикаль) Arrows Стрелки Keys: W | A | S | D Клавиши: W | A | S | D NumPad Цифровая клавиатура None Отсутствует Dpad Mode: Режим Крестовины: &Name: &Название: 4 Way Cardinal 4-ходовой основной 4 Way Diagonal 4-ходовой диагональный DPad Delay: Задержка DPad: Time lapsed before a direction change is taken into effect. Время, прошедшее до вступления в силу изменений направления движения. s с Specify the name of a dpad. Укажите название для крестовины. Mouse Settings Настройки мыши Standard Стандартный Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Стандартный: 8-позиционный стик, где диагональным направлениям соответствуют две активные кнопки. Независимый: 8-позиционный стик, в котором каждое направление имеет отдельную кнопку. Одномоментно может быть активна лишь одна кнопка. Полезно в рогаликах. 4-ходовой прямой: 4-х позиционный стик, соответствующий сторонам света. Полезно в меню. 4-ходовой диагональный: 4-х позиционный стик, перемещающийся по диагоналям. Eight Way Независимый Set Установки для Set %1 Набор %1 EditAllDefaultAutoProfileDialog Default Profile Профиль по умолчанию Profile: Профиль: Browse Обзор Open Config Открыть конфигурацию Profile file path is invalid. Путь до профиля неверен. ExtraProfileSettingsDialog Extra Profile Settings Дополнительные настройки профиля Key Press Time: Время нажатия клавиш: 0.00 ms 0,00 мс Profile Name: Имя профиля: s сек GameController Game Controller Геймпад GameControllerDPad DPad Крестовина GameControllerMappingDialog Game Controller Mapping Сопоставление игрового контроллера <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> <html><head/><body><p>antimicrox использует <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">API игрового контроллера</span></a>, предоставляемый SDL 2, чтобы абстрагировать различные геймпады для соответствия единому стандарту. Чтобы назначить кнопку, выделите ячейку для сопоставления соответствующей ячейки ниже. Затем вы можете нажать кнопку или переместить ось на своем геймпаде, и ячейка обновится с физической кнопкой или осью, которая будет использоваться.</p><p>antimicrox будет использовать указанные вами сопоставления для сохранения назначенных ячеек, которые будут загружены в SDL.</p></body></html> A A B B X X Y Y Back Назад Start Старт Guide Гайд Left Shoulder Левый бампер Right Shoulder Правый бампер Left Stick Click Кнопка левого стика Right Stick Click Кнопка правого стика Left Stick X Ось X левого стика Left Stick Y Ось Y левого стика Right Stick X Ось X правого стика Right Stick Y Ось Y правого стика Left Trigger Левый курок Right Trigger Правый курок DPad Up Крестовина вверх DPad Left Крестовина влево DPad Down Крестовина вниз DPad Right Крестовина вправо Mapping Настройка SDL 2 Game Controller Mapping String Вывод настройщика контроллеров SDL 2 Last Axis Event: Последнее событие оси: Current Axis Detection Dead Zone: Обнаружение мертвой зоны текущей оси: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Сопоставление игровых контроллеров (%1) (#%2) Discard Controller Mapping? Сбросить сопоставление контроллера? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. Сбросить сопоставление для этого контроллера? Если сбросить сопоставление, контроллер вернется к своему изначальному состоянию после обновления всех геймпадов. GameControllerSet Back Назад Guide Гайд Start Start LS Click Левый стик RS Click Правый стик L Shoulder Л бампер R Shoulder П бампер L Trigger Левый курок R Trigger Правый курок GameControllerTrigger Trigger Курок JoyAccelerometerButton Up Вверх Down Вниз Left Влево Right Вправо Shock Удар JoyAccelerometerSensor Accelerometer Акселерометр JoyAxis Axis Ось JoyAxisButton Negative Отрицательно Positive Положительно Unknown Неизвестно Button Кнопка JoyAxisContextMenu Mouse (Horizontal) Мышь (горизонталь) Mouse (Inverted Horizontal) Мышь (инвертированная горизонталь) Mouse (Vertical) Мышь (вертикаль) Mouse (Inverted Vertical) Мышь (инвертированная вертикаль) Arrows: Up | Down Стрелки: Вверх | Вниз Arrows: Left | Right Стрелки: Влево | Вправо Keys: W | S Клавиши: W | S Keys: A | D Клавиши: A | D NumPad: KP_8 | KP_2 NumPad: 8 | 2 NumPad: KP_4 | KP_6 NumPad: 4 | 6 None Отсутствует Mouse Settings Настройки мыши Left Mouse Button Левая кнопка мыши Right Mouse Button Правая кнопка мыши JoyButton Processing turbo for #%1 - %2 Обработка турбо для #%1 - %2 Finishing turbo for button #%1 - %2 Завершение турбо для кнопки #%1 - %2 Distance change for button #%1 - %2 Изменение расстояния для кнопок #%1 - %2 Button Кнопка [NO KEY] [НЕ ЗАДАНО] [Set %1 1W] [Установить %1 1W] [Set %1 2W] [Установить %1 2W] [Set %1 WH] [Установить %1 Втч] JoyButtonContextMenu Toggle Переключатель Turbo Турбо Clear Очистить Set Select Установить выбор Disabled Отключено Set %1 Набор %1 Set %1 1W Набор %1 1W Set %1 2W Набор %1 2W Set %1 WH Набор %1 WH JoyButtonSlot Mouse Мышь Up Вверх Down Вниз Left Влево Right Вправо LB LB MB MB RB RB Pause Пауза Hold Удерживание Cycle Цикл Distance Дистанция Release Отпускание Mouse Mod Скорость мыши Press Time Время нажатия Delay Задержка Load %1 Загрузка %1 Set Change %1 Изменение набора %1 [Text] %1 [Текст] %1 [Exec] %1 [Выполнение] %1 [NO KEY] [НЕ ЗАДАНО] JoyControlStick Stick Стик JoyControlStickButton Up Вверх Down Вниз Left Влево Right Вправо Button Кнопка JoyControlStickContextMenu Mouse (Normal) Мышь (нормально) Mouse (Inverted Horizontal) Мышь (инвертированная горизонталь) Mouse (Inverted Vertical) Мышь (инвертированная вертикаль) Mouse (Inverted Horizontal + Vertical) Мышь (инвертированная горизонталь + вертикаль) Arrows Стрелки Keys: W | A | S | D Клавиши: W | A | S | D NumPad Цифровая клавиатура None Отсутствует Standard Стандартный Eight Way Независимый 4 Way Cardinal 4-ходовой основной 4 Way Diagonal 4-ходовой диагональный Mouse Settings Настройки мыши JoyControlStickEditDialog Dialog Окно X: Х: 0 0 Y: Y: Distance: Дистанция: Presets: Пресет: Mouse (Normal) Мышь (нормально) Mouse (Inverted Horizontal) Мышь (инвертированная горизонталь) Mouse (Inverted Vertical) Мышь (инвертированная вертикаль) Mouse (Inverted Horizontal + Vertical) Мышь (инвертированная горизонталь + вертикаль) Arrows Стрелки Keys: W | A | S | D Клавиши: W | A | S | D NumPad Цифровая клавиатура None Отсутствует Stick Mode: Режим стика: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Стандартный: 8-позиционный стик, где диагональным направлениям соответствуют две активные кнопки. Независимый: 8-позиционный стик, в котором каждое направление имеет отдельную кнопку. Одномоментно может быть активна лишь одна кнопка. Полезно в рогаликах. 4-ходовой прямой: 4-х позиционный стик, соответствующий сторонам света. Полезно в меню. 4-ходовой диагональный: 4-х позиционный стик, перемещающийся по диагоналям. 4 Way Cardinal 4-ходовой основной 4 Way Diagonal 4-ходовой диагональный Modifier Zone: Зона модификаторов: Dead zone value to use for an analog stick. Значение мертвой зоны для аналогового стика. Value when an analog stick is considered moved 100%. Значение, при котором аналоговый стик считается перемещенным на 100%. The area (in degrees) that each diagonal region occupies. Площадь (в градусах), которую занимает каждая из диагональных областей. Square Stick: Квадратный стик: Percentage to modify a square stick coordinates to confine values to a circle Процент ограничений изменения координат квадратного стика кругом % % Stick Delay: Задержка стика: Time lapsed before a direction change is taken into effect. Время, прошедшее до вступления в силу изменений направления движения. s с Modifier: Модификатор: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Кнопка редактирования, которая активна, пока активен стик. Эта кнопка полезна для назначения зон с клавишами-модификаторами, которые можно использовать для назначения функций ходьбы/бега аналоговому стику. PushButton Кнопка Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Порог, при котором активируется кнопка модификатора. Эта кнопка полезна для назначения зон с кнопками-модификаторами, которые можно использовать для назначения функций ходьбы/бега аналоговому стику. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Определяет, активируются ли кнопки-модификаторы, когда стик находится внутри или за пределами порогового значения. Эта кнопка полезна для назначения зон с кнопками-модификаторами, которые могут быть использованы для назначения функций ходьбы/бега аналоговому стику. Invert Modifier Zone Инвертировать зону модификатора Na&me: Name: Имя: Specify the name of an analog stick. Укажите имя для аналогового стика. Mouse Settings Настройки мыши Standard Стандартный Bearing: Точка Опоры: % Safe Zone: % Зона безопасности: Eight Way Независимый Dead Zone: Мертвая зона: Max Zone: Лимит: Diagonal Range: Диагональный диапазон: Set Установки для Set %1 Установки для %1 JoyControlStickModifierButton Modifier Модификатор JoyDPad DPad Крестовина JoyDPadButton Up Вверх Down Вниз Left Влево Right Вправо Button Кнопка JoyGyroscopeButton Pitch Up Увеличение высоты Pitch Down Уменьшение высоты Yaw Left Уклон влево Yaw Right Уклон вправо Roll Left Перекат влево Roll Right Перекат вправо JoyGyroscopeSensor Gyroscope Гироскоп JoySensorButton Button Кнопка JoySensorContextMenu Mouse Settings Настройки мыши JoySensorEditDialog Dialog Окно 0 0 Acceleration (m/s^2): Ускорение (м/с^2): Pitch (°): Угол наклона (°): Roll (°): Крен (°): % Safe Zone: % Зона безопасности: Presets: Пресеты: Dead Zone: Мертвая зона: Dead zone value to use for an analog sensor. Ограничение зоны аналогового датчика. Max Zone: Лимит: Value when an analog sensor is considered moved 100%. Значение, когда аналоговый датчик считается перемещенным на 100%. Diagonal Range: Диагональный диапазон: The area (in degrees) that each diagonal region occupies. Площадь (в градусах), которую занимает каждая из диагональных областей. Sensor Delay: Задержка датчика: Time lapsed before a direction change is taken into effect. Время, прошедшее до вступления в силу изменений направления движения. s с Na&me: &Имя: Specify the name of an analog sensor. Укажите название аналогового датчика. Mouse Settings Настройки мыши Roll (°/s) Крен (°/с) Pitch (°/s) Угол наклона (°/с) Yaw (°/s) Угол отклонения (°/с) Set Установить Set %1 Установить %1 JoySensorPreset None Ничего Mouse (Normal) Мышь (нормально) Mouse (Inverted Horizontal) Мышь (инвертированная горизонталь) Mouse (Inverted Vertical) Мышь (инвертированная вертикаль) Mouse (Inverted Horizontal + Vertical) Мышь (инвертированная горизонталь + вертикаль) Arrows Стрелки Keys: W | A | S | D Клавиши: W | A | S | D NumPad Цифровая клавиатура JoyTabWidget <New> <Новый> Battery level of controller Уровень заряда батареи контроллера Remove Удалить Remove configuration from recent list. Удалить конфигурацию из списка недавно использованных файлов. Load Загрузить Load configuration file. Загрузить файл конфигурации. Save Сохранить Save changes to configuration file. Сохранить изменения в файл конфигурации. Save As Сохранить как Save changes to a new configuration file. Сохранить изменения в новый файл конфигурации. Sets Наборы Copy from Set Копировать из набора Settings Настройки Set 1 Набор 1 Set 2 Набор 2 Set 3 Набор 3 Set 4 Набор 4 Set 5 Набор 5 Set 6 Набор 6 Set 7 Набор 7 Set 8 Набор 8 Stick/Pad Assign Назначение стиков/крестровин Controller Mapping Сопоставление контроллера Quick Set Быстрая настройка Names Бирки Toggle button name displaying. Вкл. / Выкл. отображение названий команд на кнопках. Pref Настройки Профиля Change global profile settings. Изменить общие настройки профиля. Reset Сброс Revert changes to the configuration. Reload configuration file. Отменяет изменения конфигурации. Перезагружает конфигурационный файл. Open Config Открыть конфигурацию Config Files (*.amgp *.xml) Файлы конфигурации (*.amgp *.xml) Config File (*.%1.amgp) Файл конфигурации (*.%1.amgp) Do you really want to reset buttons settings for joystick? Вы действительно хотите сбросить настройки кнопок для джойстика? Save Profile Changes? Сохранить изменения в профиле? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Изменения в новом профиле не были сохранены. Сохранить или отменить изменения в текущем профиле? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Изменения в профиле "%1" не были сохранены. Сохранить или отменить изменения в текущем профиле? Sticks Стики Sensors Датчики DPads Крестовины No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Не назначено ни одной кнопки. Воспользуйтесь "Быстрой настройкой" для назначения кнопок или отключите сокрытие пустых кнопок. Set %1: %2 Набор %1: %2 Set %1 Набор %1 Copy Set Assignments Скопировать набор назначений Are you sure you want to copy the assignments and device properties from %1? Вы уверены, что хотите скопировать настройки и параметры устройства из %1? Save Config Сохранить конфигурацию Set Набор Joystick Joystick Геймпад JoystickStatusWindow Properties Свойства Details Подробности Name: Имя: %1 %1 Number: Номер: Axes: Осей: Buttons: Кнопок: Hats: Мини-джойстиков: Sensors: Датчики: Battery: Батарея: Unknown Неизвестно GUID: GUID: Game Controller: Игровой контроллер: Axes Оси Buttons Кнопки Hats Мини-джойстики Sensors Датчики %1 (#%2) Properties %1 (#%2) Свойства Empty Пусто Low Низкий Medium Средний Full Полный Wired Проводной Different: %1 Разное: %1 Accelerometer + Gyroscope Акселерометр + гироскоп Accelerometer Акселерометр Gyroscope Гироскоп None Ничего Axis %1 Ось %1 Hat %1 Мини-джойстик %1 No Нет Yes Да MainSettingsDialog Edit Settings Редактировать настройки General Общие Controller Mappings Сопоставление контроллера Language Язык Auto Profile Авто-профиль Mouse Мышь Advanced Расширенный <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Укажите путь до директории, которую программа будет использовать для хранения профилей.</p></body></html> Recent Profile Count: Количество недавних профилей: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Количество профилей, которые будут хранится в списке недавних. Если выставить "0" то программа не будет ограничивать количество отображаемых профилей.</p></body></html> Gamepad Poll Rate: Частота опроса геймпада: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Изменить скорость опроса, которую программа использует для обнаружения новых событий с геймпадов. По умолчанию установлено значение 10 мс. Уменьшение значения времени опроса может привести к тому, что приложение будет потреблять больше процессорного времени поэтому, пожалуйста, протестируйте эту настройку перед полноценным использованием AntiMicroX. Hide main window when the main window close button is clicked instead of quitting the program. Прятать главное окно программы по нажатию на кнопку выхода вместо того чтобы закрывать программу. Close To Tray Сворачивать в трей при закрытии Have Windows start AntiMicroX at system startup. Пусть Windows запускает AntiMicroX при запуске системы. Launch At Windows Startup Загружать вместе с Windows Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Отображает недавно открытые профили для всех контроллеров в виде единого списка под иконкой в системном лотке. По умолчанию использует подменю. Single Profile List in Tray Единый лист профилей в трее Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Заставляет программу сворачиваться в панель задач. По умолчанию программа сворачивается в системный лоток. Minimize to Taskbar Сворачивать в панель задач This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Эта опция заставит программу скрывать все кнопки, к которым не привязаны слоты с командами. Воспользуйтесь окном "Быстрой Настройки" для отображения скрытых кнопок. Hide Empty Buttons Скрыть пустые кнопки When the program is launched, open the last known profile that was opened during the previous session. Когда программа запустится, будет открыт последний профиль, использованный в предыдущей сессии. Auto Load Last Opened Profile Автоматически загружать последний открытый профиль Only show the system tray icon when the program first launches. При запуске программы появится лишь значок в системном трее. Launch in Tray Запуск в свернутом виде Associate .amgp files with AntiMicroX in Windows Explorer. Ассоциировать файлы .amgp с AntiMicroX в проводнике Windows. Associate Profiles Привязка профилей Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Помните, что она не будет работать, если к компьютеру не подключена такая клавиатура или если она не встроена, как в настольных ПК. Attach the numeric keypad Присоедините цифровую клавиатуру Show low battery notification Отображать уведомление о низком заряде батареи Show empty battery notification Отображать уведомление о разряженной батарее Key Repeat Повтор клавиш Active keys will be repeatedly pressed when this option is enabled. Если активировать данную опцию то активные клавиши будут нажиматься автоматически. Enable Включить Specifies how much time should elapse before key repeating begins. Указывает, сколько времени должно пройти до начала повтора клавиш. Specifies how many times key presses will be performed per seconds. Указывает, сколько раз будут выполняться нажатия клавиш в секунду. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntiMicroX был переведен на множество различных языков. По умолчанию программа выбирает подходящий перевод, основываясь на настройках языка вашей системы. Однако вы можете заставить AntiMicroX загружать другой перевод в зависимости от языка, который вы выберете из списка ниже.</p></body></html> Português do Brasil Португальский бразильский Français Французский Deutsch Немецкий Italiano Итальянский 日本語 Японский Русский Русский српски / srpski Сербский 简体中文 Китайский (упрощенный) Español Испанский українська Украинский Polski Польский History Si&ze: Разм&ер истории: Weight Modi&fier: Модифик&атор массы: Log File: Файл журнала: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> <html><head/><body><p><span style=" font-style:italic;">Примечание Неопределенный файл журнала позволяет печатать журналы в консольном выводе</span></p></body></html> Log Level: Уровень журналирования: None Ничего Error Ошибки Warning Предупреждения Info Информация Verbose Подробнее Debug Отладка Note: To see the change of log level in console output (not in log file), application restart is required Примечание: Чтобы увидеть изменение уровня журнала в консольном выводе (не в файле журнала), требуется перезапуск приложения Reset Сбросить Class Класс Title Заголовок Program Программа Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Отключите настройку Windows "Повысить точность указателя" во время работы AntiMicroX. Отключение "Повышение точности указателя" позволит сделать перемещение мыши в AntiMicroX более точным. Disable Enhance Pointer Precision Выключить улучшенную точность курсора Smoothing Плавность Refresh Rate: Частота обновления: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Частота обновления - это количество времени, которое будет проходить между событиями мыши. Пожалуйста, будьте осторожны при редактировании этой настройки, так как это приведет к тому, что программа будет использовать больше мощности процессора. Установка слишком низкого значения может привести к нестабильности системы. Пожалуйста, протестируйте эти настройки, прежде чем использовать программу полноценно. Spring Пружина Screen: Экран: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Используйте указанный экран для режима spring. В Linux по умолчанию используется основной экран. В Windows по умолчанию используются все доступные экраны. Accel Numerator: Числитель ускорения: 0 0 Accel Denominator: Знаменатель ускорения: Accel Threshold: Порог ускорения: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Если значения ускорения для виртуальной мыши были изменены другим процессом, особенно при выходе из старой игры, то вам, возможно, захочется сбросить значения ускорения используемое виртуальной мышью. Reset Acceleration Сброс ускорения Delay: Задержка: Pro&file Directory: Каталог пр&офилей: ms мс Rate: Частота: times/s раз/сек Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. Ниже приведен сохраненный список из пользовательских настроек. Вы можете использовать эту таблицу, чтобы удалять настройки или же временно их отключать. Также Вы можете отключить настройки, входящие в SDL - просто добавьте новую строку с соответствующим GUID геймпада и активируйте чекбокс "Отключить" Изменения не вступят в силу пока вы не обновите или переподключите все геймпады. GUID GUID Mapping String Строка сопоставлений Disable? Отключить? Delete Удалить Default По умолчанию English Английский Active Активировать Devices: Устройства: All Все Device Устройство Profile Профиль Default? По умолчанию? Add Добавить Edit Редактировать AutoProfile (disabled in Wayland) Автопрофиль (отключено в Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Также, пользователи Windows, которые хотят установить низкие значения могут включить настройку "Выключить улучшенную точность курсора" если вы не выключили эту настройку в самом Windows. Select Default Profile Directory Выбрать в качестве профиля по умолчанию Are you sure you want to delete the profile? Вы уверены, что хотите удалить этот профиль? Save Log File As Сохранить журнал приложения как Log Files (*.log) Файл журнала приложения (*.log) Do you really want to reset setting? Вы уверены, что хотите сбросить эту настройку до значения по умолчанию? Would you like to reset mappings too? Хотите ли вы также сбросить назначенные клавиши? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu Геймпады не обнаружены. Пожалуйста, подключите геймпад к компьютеру и выберете опцию "Найти геймпады" из главного меню. If events are not seen by a game, please click here to run this application as Administrator. Если нажатия не распознаются игрой, нажмите сюда, чтобы перезапустить приложение с правами Администратора. Update Button Кнопка обновления &App &Приложение &Options &Настройки He&lp &Помощь &Quit &Выход Ctrl+Q Ctrl+Q &Update Joysticks &Обновить геймпады Ctrl+U Ctrl+U &Hide &Скрыть Ctrl+H Ctrl+H &About &О программе Ctrl+A Ctrl+A About &Qt О проекте &Qt Ctrl+T Ctrl+T &Properties &Настройки геймпадов Ctrl+P Ctrl+P &Key Checker &Проверка клавиш Ctrl+K Ctrl+K &GitHub Page &Страница на GitHub Ctrl+G Ctrl+G S&ettings Н&астройки Ctrl+S Ctrl+S &Stick/Pad Assign &Назначение Стиков Геймпада Ctrl+X Ctrl+X &Wiki &Вики Ctrl+W Ctrl+W &Issues &Сообщить о проблеме Ctrl+I Ctrl+I &Calibration &Калибровка Ctrl+C Ctrl+C Home Page Домашняя страница (%1) (%1) Open File Открыть файл Run as Administrator? Запустить от имени Администратора? Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. Вы уверены, что хотите запустить эту программу от имени Администратора? Некоторые игры запускаются от имени Администратора, что приводит к тому, что события, генерируемые antimicro, не могут использоваться этими играми, если antimicro также не запущен от имени Администратора. Это происходит из-за проблем с разрешениями, вызванных опциями User Account Control (UAC) в Windows Vista и более поздних версиях. Failed to elevate program Не удалось получить права Администратора Failed to restart this program as the Administrator Не удалось перезапустить программу с правами Администратора %1 battery %1 заряд батареи Battery level is less than %1 Заряд батареи меньше чем %1 Device number: %1 Device name: %2 Номер устройства: %1 Имя устройства: %2 Update to %1 available Доступно обновление до %1 Reading old profile Чтение старого профиля This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 В этом профиле используются номера GUID контроллеров. Вы хотите изменить GUID номера на UniqueID в этом файле для использования в идентичных геймконтроллерах? Такой старый файл не может быть загружен в antimicrox начиная с версии 2.25 &Restore &Восстановить Calibration couldn't be opened Не получилось открыть окно калибровки You must connect at least one controller to open the window Необходимо подключить хотя бы одно устройство, чтобы открыть это окно MouseAxisSettingsDialog Mouse Settings - Настройки мыши - Set %1 Установки для %1 MouseButtonSettingsDialog Mouse Settings - Настройки мыши - Set %1 Установки для %1 MouseControlStickSettingsDialog Mouse Settings Настройки мыши Set %1 Установки для %1 MouseDPadSettingsDialog Mouse Settings Настройки мыши Set %1 Установки для %1 MouseSensorSettingsDialog Mouse Settings Наcтройки мыши Set %1 Установить %1 MouseSettingsDialog Mouse Settings Настройки мыши Mouse Mode: Режим мыши: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Режим Курсора используется для перемещения курсора мыши по экрану по отношению к текущей позиции в зависимости от того, насколько вы переместили ось, или при нажатии кнопки. Режим Пружины используется для перемещения курсора мыши от центра экрана в зависимости от того, насколько вы переместили ось. Курсор мыши будет возвращен в центр экрана, когда ось переместится обратно к мертвой зоне. Cursor Курсор Spring Пружина Acceleration: Ускорение: Enhanced Precision Повышенная точность Linear Линейное Quadratic Квадратное Cubic Кубическое Quadratic Extreme Вершина параболы Power Function Степенная функция Easing Quadratic Ослабевающее квадратичное Easing Cubic Ослабевающее кубическое Mouse Speed Settings Настройки скорости мыши Enable to change the horizontal and vertical speed boxes at the same time. Позволяет увеличивать скорость мыши по горизонтали и вертикали одновременно. Change Together Изменять совместно Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Опции для добавления большего ускорения к движению мыши движения за пределами того, что может дать кривая ускорения производить. Ускорение добавляется на основе того, как быстро ось перемещается за один опрос геймпада. Это предназначено для того, чтобы помочь обойти некоторые проблемы, связанные с очень ограниченным диапазоном входных сигналов, доступных при использовании типичных аналоговых стиков геймпада. Delta Acceleration &Multiplier: &Множитель: Mi&n Threshold: &Мин порог: 1 = 20 pps 1 = 20 pps Wheel Hori. Speed: Скорость колесика по горизонтали: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Устанавливает скорость движения колесика мыши по горизонтали. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Устанавливает скорость движения колесика мыши по вертикали. Sensitivit&y: Чувств&ительность: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: Длительность Замедления: s с Highest value to accelerate mouse movement by Наибольшее значение для ускорения движения мыши на x x Start %: Acceleration begins at this percentage of the base multiplier Ускорение начинается с этого процента от базового множителя Minimum amount of axis travel required for acceleration to begin Минимальная величина перемещения оси, необходимая для начала ускорения Max Threshold: Макс порог: Maximum axis travel before acceleration has reached the multiplier value Максимальный ход оси до того, как ускорение достигнет значения множителя E&xtra Duration: Curve: Кривая: Ease Out Sine Синусоида Замедления Ease Out Quad Квадрат Замедления Ease Out Cubic Куб Замедления Release Radius: Радиус действия: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Привязывает пружину к позиции мыши. Relative Привязка Mouse Status Состояние мыши X: Х: 0 (0 pps) 0 (0 импульсов в секунду) Y: Y: 1 = 1 notch(es)/s 1 = 1 шаг(ов)/сек Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Улучшенный: Трехуровневая кривая, которая заставляет мышь двигаться медленно на низком конце оси и быстро на высоком конце. Линейный: Мышь движется пропорционально оси. Квадратичный: Мышь медленно разгоняется на низком уровне. Кубический: Мышь ускоряется медленнее, чем Quadratic. Квадратичный экстремум: Увеличивает скорость мыши в 1,5 раза после того, как достигнуто 95% перемещения по оси. Power Function: Позволяет создать индивидуальную кривую. Квадратичное ускорение: Высокая точка оси постепенно ускоряется в течение определенного периода времени с помощью квадратичной кривой. Кубическое ускорение: Высшая точка оси постепенно ускоряется в течение периода времени с помощью кубической кривой. Hori&zontal Speed: Скорость по горизонт&али: &Vertical Speed: Скорость по &вертикали: Wheel Vert. Speed: Скорость колесика по вертикали: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. Определяет количество времени (в секундах), которое потребуется до полного ускорения мыши после достижения верхней точки оси. % % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Увеличение времени действия дополнительного ускорения. Перемещение оси будет учитываться. Более медленный щелчок уменьшит фактическое время применения дополнительного ускорения. Spring Settings Настройки Пружины Spring Width: Ширина пружины: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Изменяет ширину области, по которой будет двигаться курсор в режиме Пружины. Если выставить "0" будет использоваться вся ширина экрана. Spring Height: Высота пружины: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. Изменяет высоту области, по которой будет двигаться курсор в режиме Пружины. Если выставить "0" будет использоваться вся высота экрана. %n notch(es)/s %n шаг/сек %n шага/сек %n шагов/сек QKeyDisplayDialog Key Checker Проверка клавиш <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> <html><head/><body><p>Нажмите клавишу на клавиатуре, чтобы увидеть, как эта клавиша определяется этим приложением. В окне будет показано нативное значение клавиши, возвращаемое Qt значение (если применимо), и пользовательское значение, используемое AntiMicroX.</p><p>Значения AntiMicroX и Qt обычно совпадают. AntiMicroX старается использовать значения клавиш, определенные в Qt, когда это возможно. Посмотрите на странице <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> список значений, определенных Qt. Если вы обнаружите, что какая-либо клавиша не поддерживается данной программой, пожалуйста, сообщите о проблеме на <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub-страничке</span></a> AntiMicroX, чтобы программа могла быть отредактирована для её поддержки. Однако, даже сейчас к неизвестным значениям добавляется специальный префикс, поэтому их всё ещё можно использовать; основная проблема заключается в том, что профиль не будет переносимым.</p></body></html> Event Handler: Обработчик событий: Native Key Value: Родное значение клавиши: 0x00000000 0x00000000 Qt Key Value: Значение клавиши в Qt: antimicro Key Value: Значение клавиши antimicro: QObject Super Супер Menu Меню Mute Отключить звук Vol+ Громкость+ Vol- Громкость- Play/Pause Воспроизведение/Пауза Play Воспроизведение Pause Пауза Prev Предыдущий Next Следующий Mail Электронная почта Home Домашняя страница Media Медиа Search Поиск Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Ваши первоначальные настройки (ранее сохраненные в %1) были скопированы в %2 При желании вы можете удалить исходный каталог или оставить все как есть. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Возникла проблема с переносом настроек. Оригинальные конфигурации хранятся в %1 но их новое местоположение: %2 Вы можете выполнить миграцию вручную, переименовав старый каталог и переименовав файл в antimicrox_settings.ini. Quitting Program Выход из программы # of joysticks found: %1 # найденных джойстиков: %1 List Joysticks: Список джойстиков: --------------- --------------- Joystick %1: Джойстик %1: Attempting to use fallback option %1 for event generation. Попытка использовать опцию отката %1 для генерации событий. Failed to open event generator. Exiting. Не удалось открыть генератор событий. Выход. Using %1 as the event generator. Использование %1 в качестве генератора событий. Last button Последняя кнопка There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? В данных нет последней нажатой кнопки с геймпада. Установили ли вы хотя бы одну кнопку с геймпада для клавиатуры? Specified contradicting flags: --show and --hidden Указаны противоречащие друг другу флаги: --show и --hidden Profile location %1 is not an XML file. Профиль, находящийся в %1, не является XML файлом. Profile location %1 does not exist. Профиль, который должен находиться в %1, не существует. Controller identifier is not a valid value. Идентификатор контроллера имеет недопустимое значение. An invalid set number '%1' was specified. Был указан недопустимый номер набора '%1'. Controller identifier '%s'' is not a valid value. Идентификатор контроллера '%s'' не является допустимым значением. No set number was specified. Не указан набор значений. An invalid event generator was specified. Был указан недопустимый генератор событий. No event generator string was specified. Не указана строка генератора событий. Unknown log level: Неизвестный уровень журнала: No log file specified. Не указан файл журнала. xinput version must be at least 2.0. No mouse acceleration changes will occur. Версия xinput должна быть не ниже 2.0. Изменения ускорения мыши не произойдет. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: Невозможно открыть файлы uinput, это может вызвать проблемы с генерацией событий. Для проверки возможных решений, пожалуйста, посетите: QuickSetDialog Quick Set Быстрая настройка <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>Пожалуйста, нажмите на кнопку или сдвиньте стик на %1 (<span style=" font-weight:600;">%2</span>).<br/>Затем появится окно, которое позволит <br/>вам назначить кнопку.</p></body></html> Quick Set %1 Быстрая Настройка %1 SetAxisThrottleDialog Throttle Change Смена Тяги The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? Настройки профиля для Оси %1 были изменены. Желаете применить эти настройки ко всем наборам? SetJoystick Set %1: %2 Набор %1: %2 Set %1 Набор %1 SetNamesDialog Set Name Settings Установить имена для наборов Set 1 Набор 1 Set 2 Набор 2 Set 3 Набор 3 Set 4 Набор 4 Set 5 Набор 5 Set 6 Набор 6 Set 7 Набор 7 Set 8 Набор 8 Name Имя SimpleKeyGrabberButton Mouse Мышь SpringModeRegionPreview Spring Mode Preview Предпросмотр Режима Пружины UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Не удалось найти действительный файл устройства uinput. Пожалуйста, проверьте, загружен ли у вас модуль uinput. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Не удалось открыть файл устройства uinput Убедитесь, что у вас есть разрешение на запись в устройство Using uinput device file %1 Использование файла устройства uinput %1 UInputHelper a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z Esc Esc F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace BackSpace Tab Tab [ [ ] ] \ \ CapsLock CapsLock ; ; ' ' Enter Enter Shift_L Shift_Л , , . . / / Ctrl_L Ctrl_Л Super_L Super_Л Alt_L Alt_Л Space Пробел Alt_R Alt_П Menu Меню Ctrl_R Ctrl_П Shift_R Shift_П Up Вверх Left Влево Down Вниз Right Вправо PrtSc PrtSc Ins Ins Del Del Home Home End End PgUp PgUp PgDn PgDn NumLock NumLock * * + + KP_Enter KP_Enter KP_1 KP_1 KP_2 KP_2 KP_3 KP_3 KP_4 KP_4 KP_5 KP_5 KP_6 KP_6 KP_7 KP_7 KP_8 KP_8 KP_9 KP_9 KP_0 KP_0 SCLK SCLK Pause Pause Super_R Super_П Mute Mute VolDn VolDn VolUp VolUp Play Play Stop Stop Prev Prev Next Next [NO KEY] [НЕ ЗАДАНО] UnixWindowInfoDialog Captured Window Properties Свойства захваченного окна Information About Window Информация об окне Class: Класс: TextLabel Метка текста Title: Заголовок: Path: Путь: Match By Properties Сопоставление по свойствам Class Класс Title Заголовок Path Путь VDPad VDPad Виртуальная Крестовина VirtualKeyPushButton Space Пробел Tab Tab Shift (L) Shift (Л) Shift (R) Shift (П) Ctrl (L) Ctrl (Л) Ctrl (R) Ctrl (П) Alt (L) Alt (Л) Alt (R) Alt (П) Alt Gr Alt Gr ` ` ~ ~ - - = = [ [ ] ] \ \ Caps Caps ; ; ' ' , , . . / / ESC ESC PRTSC PRTSC SCLK SCLK INS INS PGUP PGUP DEL DEL PGDN PGDN 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK NUM LK * * + + Enter Enter Del Del < < : : Super (L) Super (Л) Menu Меню Up Вверх Down Вниз Left Влево Right Вправо VirtualKeyboardMouseWidget Keyboard Клавиатура Mouse Мышь Mouse Settings Наcтройки мыши Left Mouse Влево Up Mouse Вверх Left Button Mouse Левая кнопка Middle Button Mouse Средняя кнопка Right Button Mouse Правая кнопка Wheel Up Mouse Колёсико вверх Wheel Left Mouse Колёсико влево Wheel Right Mouse Колёсико вправо Wheel Down Mouse Колёсико вниз Down Mouse Вниз Right Mouse Вправо Button 4 Mouse Кнопка 4 Mouse 8 Mouse Mouse 8 Button 5 Mouse Кнопка 5 Mouse 9 Mouse Mouse 9 NONE ПУСТО [NO KEY] [НЕ ЗАДАНО] Last button Последняя кнопка Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Слоты для кнопок не могут быть очищены, потому что не было задано ни одной кнопки с клавиатуры под геймпад. Установите хотя бы одну кнопку с клавиатуры под геймпад Others Другие Applications Меню Browser Back Браузер назад Browser Favorites Избранное браузера Browser Forward Браузер вперёд Browser Home Браузер домой Browser Refresh Обновление браузера Browser Search Поиск в браузере Browser Stop Браузер стоп Calc Калькулятор Email Email F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media Media Media Next Media Next Media Play Воспроизвести Media Previous Предыдущий медиа Media Stop Media Stop Search Поиск Volume Down Volume Down Volume Mute Заглушить звук Volume Up Volume Up VirtualMousePushButton INVALID ОШИБКА WinAppProfileTimerDialog Capture Application Звхватить Приложение After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. После нажатия на кнопку "Захватить Приложение" кликните по приложению с которым хотите ассоциировать данный профиль. Активное приложение будет захвачено после выбранного количества секунд. Timer: Таймер: Seconds Секунды Cancel Отмена WinExtras [NO KEY] [НЕ ЗАДАНО] AntiMicro Profile AntiMicro профиль X11Extras ESC ESC Tab Tab Space Пробел DEL DEL Return Return KP_Enter KP_Enter Backspace Backspace Alt Gr Alt Gr xinput extension was not found. No mouse acceleration changes will occur. Расширение xinput не найдено. Изменения ускорения мыши не сохранены. xinput version must be at least 2.0. No mouse acceleration changes will occur. Версия xinput должна быть не ниже 2.0. Изменения ускорения мыши не произойдет. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 PtrFeedbackClass не найден для виртуального указателя.Для устройства с id=%1 изменение ускорения мыши не сохранено Changing mouse acceleration for device with id=%1 Изменение ускорения мыши для устройства с id=%1 XMLConfigReader Could not write updated profile XML to file %1. Не удалось записать обновленный XML профиля в файл %1. XMLConfigWriter Could not write to profile at %1. Не удалось записать профиль в %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Графическая программа, используемая для сопоставления кнопок клавиатуры и управления мышью с геймпадом. Пригодится для игр без поддержки геймпада. main Launch program in system tray only. Запускать программу только в системном трее. Launch program with the tray menu disabled Запустить программу с отключённым меню Launch program without the main window displayed Запуск программы без главного окна Show app window when hidden. (Used for unhiding window of already running app instance). Показывать окно приложения, когда оно скрыто. (Используется для скрытия окна уже запущенного экземпляра приложения). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers Запуск программы с файлом конфигурации, выбранным по умолчанию для выбранных контроллеров, или изменение активного профиля запущенного приложения. По умолчанию для всех контроллеров location расположение Apply configuration file to a specific controller. Value can be a controller index, name, or GUID Применить файл конфигурации к конкретному контроллеру. Значение может быть индексом контроллера, именем или GUID value значение Unload currently enabled profile(s) Выгрузить текущий включенный профиль(ы) value(s) значение(я) Start joysticks on a specific set. Value can be a controller index, name, or GUID Запуск джойстиков на определенном пресете. Значением может быть индекс контроллера, имя или GUID number value значение номера Enable logging. Levels (from the least strict): warn,info,verbose,debug Включить ведение журнала. Уровни (от наименее строгого): warn,info,verbose,debug log-type тип журнала Choose a file for logs writing Выберите файл для записи журналов filename имя файла Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. Выберите между поддержкой XTest и поддержкой uinput для генерации событий. Используется, только если вы включили опции xtest и uinput в Linux или vmulti в Windows. По умолчанию: xtest. event-generation-type тип генерации событий Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. Вывести информацию о джойстиках, обнаруженных SDL. Используется только при наличии библиотеки sdl. Вы можете проверить индекс, имя или даже GUID вашего контроллера. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_rue.ts000066400000000000000000012466241471077622000275710ustar00rootroot00000000000000 AboutDialog About Version Info Changelog Credits AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 License Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 AddEditAutoProfileDialog Auto Profile Dialog Pro&file: Browse Window: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Detect Window Properties &Class: T&itle: set partial title Application: Select De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Set as Default for Controller A different profile is already selected as the default for this device. Current (%1) Open Config Select Program Programs (*.exe) Please use the main default profile selection. Main Profile Already selected Chosen Profile The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. Capture Application Window Could not obtain information for the selected window. Application Capture Failed Profile file path is invalid. No window matching property was specified. Program path is invalid or not executable. File is not an .exe file. No window matching property was selected. AdvanceButtonDialog Advanced Assignments Toggle Turbo Set Selector Blank or KB/M Hold Pause Cycle Distance Insert Delete Clear All Time: 0.01s 0s Insert a pause that occurs in between key presses. Release Insert a new blank slot. Delete a slot. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. 0m &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: % Mouse Mod Press Time Delay Execute Load Set Change Text Entry Join Split Placeholder 0 Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After seconds Executable: ... Arguments: Enabled Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Delay: 0.10s Rate: 10.0/s Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] sec. /sec. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: Y Axis: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Down: Left: Right: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Name: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Dead Zone: Max Zone: [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Last keyboard/mouse button: Slots Na&me: Specify the name of a button. Action: Specify the action that will be performed in game while this button is being used. Advanced Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel X gain offset Y Start calibration Close Reset settings Save Calibration Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAxis Axis JoyAxisButton Negative Positive Unknown Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Up Down Left Right LB MB RB Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] JoyControlStick Stick JoyControlStickButton Up Down Left Right Button JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: 0 Y: Distance: Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Na&me: Name: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Down Left Right Button JoyTabWidget <New> Remove Remove configuration from recent list. Load Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Details Name: %1 Number: Axes: Buttons: Hats: Battery: Unknown GUID: Game Controller: Axes Buttons Hats %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Axis %1 Hat %1 No Yes MainSettingsDialog Edit Settings General Controller Mappings Language Auto Profile Mouse Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Pro&file Directory: Show low battery notification Show empty battery notification Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID Mapping String Disable? Delete Default English Active Devices: All Device Profile Default? Add Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Options He&lp &Quit Ctrl+Q &Update Joysticks Ctrl+U &Hide Ctrl+H &About Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G &Game Controller Mapping Ctrl+M S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page (%1) Open File Calibration is not available. Selected device doesn't have any joystick to calibrate. Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Failed to elevate program Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Prev Next Mail Home Media Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Index: %1 UniqueID: %1 GUID: %1 VendorID: %1 ProductID: %1 Product Version: %1 Name: %1 Yes No Game Controller: %1 # of Axes: %1 # of Buttons: %1 # of Hats: %1 Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Active window changed to: Title = "%1", Class = "%2", Program = "%3" or "%4". Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. Auto-switching to profile "%1". Auto-switching to nullptr profile! xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name SimpleKeyGrabberButton Mouse SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 2 3 4 5 6 7 8 9 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK * + Enter Del < : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard Mouse Mouse Settings Left Mouse Up Mouse Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel WinExtras [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_sr.ts000066400000000000000000013644041471077622000274170ustar00rootroot00000000000000 AboutDialog About О програму Version Издање Info Подаци Changelog Дневник измена Credits Заслуге AntiMicroX Анти-микро <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development О развоју програма "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Ауторска права: 2013 - 2022. {2013 ?} {2013 ?} License Лиценца Program Version %1 Издање програма %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Програмски код је превођен дана %1 у %2 Built Against SDL %1 Изграђен помоћу СДЛ %1 Running With SDL %1 Употребљава СДЛ %1 Using Qt %1 Уз КјуТ-библиотеке %1 Using Event Handler: %1 Употребљава руковаоца догађајима („Event Handler“) : %1 AddEditAutoProfileDialog Auto Profile Dialog Самостално профилисање Pro&file: Browse Разгледај Window: Прозор: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Одабир прозора — Притиском на одговарајући прозор програма у обрасцу се попуњава путања до датотеке програма. Detect Window Properties Сам откриј особине прозора &Class: T&itle: set partial title Application: Програм: Select Одабери De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Подразумевано поставља овај профил за дати уређај. Овај избор ће се користити уместо свеопштих опција профила. Set as Default for Controller Постави као подразумевано за контролер A different profile is already selected as the default for this device. За овај уређај је већ одабран други подразумевани профил. Current (%1) Текући (%1) Open Config Отвори подешавања Select Program Одабери програм Programs (*.exe) Програми (*.exe) Please use the main default profile selection. Користите главни избор подразумеваног профила. Main Profile Already selected Chosen Profile The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. Одабирајте прозор употребом миша, а поништите одабир тастером <Esc>. Capture Application Window Разоткривање графичког сучеља програма Could not obtain information for the selected window. Не могу да добавим податке о одабраном прозору. Application Capture Failed Није успело разоткривање програма Profile file path is invalid. Путања до датотеке профила није ваљана. No window matching property was specified. Није била одређена одговарајућа особина прозора. Program path is invalid or not executable. Путања до програма није ваљана или није извршна. File is not an .exe file. Ово није извршна датотека. No window matching property was selected. Није била одабрана одговарајућа особина прозора. AdvanceButtonDialog Advanced Напредно Assignments Придруживања Toggle Преклопник Turbo Набуџи Set Selector Изборник скупа Blank or KB/M Празно или „Таст./Миш“ Hold Држи Pause Пауза Cycle Врти Distance Раздаљина Insert Уметни Delete Уклони Clear All Уклони све Time: Време: 0.01s 0,01 сек 0s 0 сек Insert a pause that occurs in between key presses. Време између притиска два притиска дугмета. Release Пусти Insert a new blank slot. Унеси нов, празан слот. Join Split Delete a slot. Уклони слот. Clear all currently assigned slots. Уклони све већ придружене слотове. Specify the duration of an inserted Pause or Hold slot. Одређивање трајања за већ унет Пауза/Држи слот. 0m 0 мин &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Поставите област изван мртве области правца, у којој ће се извршити низ радњи. Distance: Раздаљина: % % Mouse Mod Мишар Press Time Трајање притиска Delay Кашњење Execute Изврши Load Учитај Set Change Измени скуп Text Entry Унос текста Placeholder Препознавач положаја 0 0 Set the percentage that mouse speeds will be modified by. Поставите промену брзине померања миша у процентима. Auto Reset Cycle After Самопоништавање „вртње“ након seconds секунди Executable: ... ... Arguments: Enabled Омогућено Mode: Режим: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>Обично: Узастопно притискање-пуштање дугмета одабраном брзином.</p><p>Постепено: Измена кашњења код притиска-пуштања дугмета засновано на померају осног растојањ. Брзина остаје неизмењена.</p><p>Импулсно: Измена броја притисака-пуштања дугмета по секунди. Кашњење остаје неизмењено.</p></body></html> Normal Обично Gradient Постепено Pulse Импулсно Delay: Кашњење: 0.10s 0,10 сек Rate: Брзина: 10.0/s 10,0/сек Disabled Онемогућено Select Set 1 One Way Изабери 1. скуп, једносмерно Select Set 1 Two Way Изабери 1. скуп, двосмерно Select Set 1 While Held Изабери 1. скуп, док држим Select Set 2 One Way Изабери 2. скуп, једносмерно Select Set 2 Two Way Изабери 2. скуп, двосмерно Select Set 2 While Held Изабери 2. скуп, док држим Select Set 3 One Way Изабери 3. скуп, једносмерно Select Set 3 Two Way Изабери 3. скуп, двосмерно Select Set 3 While Held Изабери 3. скуп, док држим Select Set 4 One Way Изабери 4. скуп, једносмерно Select Set 4 Two Way Изабери 4. скуп, двосмерно Select Set 4 While Held Изабери 4. скуп, док држим Select Set 5 One Way Изабери 5. скуп, једносмерно Select Set 5 Two Way Изабери 5. скуп, двосмерно Select Set 5 While Held Изабери 5. скуп, док држим Select Set 6 One Way Изабери 6. скуп, једносмерно Select Set 6 Two Way Изабери 6. скуп, двосмерно Select Set 6 While Held Изабери 6. скуп, док држим Select Set 7 One Way Изабери 7. скуп, једносмерно Select Set 7 Two Way Изабери 7. скуп, двосмерно Select Set 7 While Held Изабери 7. скуп, док држим Select Set 8 One Way Изабери 8. скуп, једносмерно Select Set 8 Two Way Изабери 8. скуп, двосмерно Select Set 8 While Held Изабери 8. скуп, док држим [NO KEY] [Без тастера] sec. сек. /sec. /сек. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Скуп %1 Select Set %1 Одабери %1. скуп One Way Једносмерно Two Way Двосмерно While Held Док држим Choose Executable Избор извршне датотеке Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Слотови изван „вртње“ ће се извршити по наредном притиску тастера. Вишеструке „вртње“ се могу додавати код стварање делова једног низа. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Покретање наредног слота биће одложено за наведено време.Слотови покренути пре овог одлагања ће остати покренути и по његовом истеку. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Овом се радњом одређује да накнадни слотови могу да се изврше само када се нека оса помери за одређени опсег изван дате мртве области. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Уметање задржавања. Слотови након дате радње ће да се изврше само ако се тастер задржи ван наведеног периода. Chose a profile to load when this slot is activated. Одабир профила који ће се учитати по укључењу овог слота. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Радња за управљањем начином рада миша ће изменити све поставке брзине миша за одређен проценат,а док је радња у току. Ово може бити корисно за успоравање миша при нишањењу. Specify the time that keys past this slot should be held down. Одређује колико ће дуго бити задржани у доњем положају (притиснути) тастери ван овог слота. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Уметање отпуштања. Слотови након дате радње ће да се изврше само по отпуштању тастера ако је он задржан ван наведеног периода. Change to selected set once slot is activated. Промени на одабрани скуп по отпочињању слота. Full string will be typed when a slot is activated. Уписује пуну ниску знакова по отпочињању слота. Execute program when slot is activated. Извршава програм по отпочињању слота. Choose Profile Одабир профила Config Files (*.amgp *.xml) Датотеке подешавања (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Придружвање Управљача/Тастера Sticks Управљачи DPads Тастери правца или смера (дирекционални) Д-тастери Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) %1 (Џојстик %2) Stick 1 Управљач 1 Enabled Омогућен Assign Придружи X Axis: »X« правац: Y Axis: »Y« правац: Stick 2 Управљач 2 Number of Physical DPads: %1 Број стварних Д-тастера: %1 Virtual DPad 1 Патворено = Виртуелно Патворен Д-тастатер 1 Up: Горе: Down: Доле: Left: Лево: Right: Десно: Axis %1 Правац %1 Axis %1 - Правац %1 - Axis %1 + Правац %1 + Button %1 Дугме %1 Move stick 1 along the X axis Померајте по »Х-оси« 1. управљач Move stick 1 along the Y axis Померајте по »У-оси« 1. управљач Move stick 2 along the X axis Померајте по »Х-оси« 2. управљач Move stick 2 along the Y axis Померајте по »У-оси« 2. управљач Press a button or move an axis Притисните тастер или померите управљач AxisEditDialog Axis Правац Mouse (Horizontal) Миш (водоравно) Mouse (Inverted Horizontal) Миш (обрнуто водоравно) Mouse (Vertical) Миш (усправно) Mouse (Inverted Vertical) Миш (обрнуто усправно) Arrows: Up | Down Стрелице: Горе | Доле Arrows: Left | Right Стрелице: Лево | Десно Keys: W | S Тастери: Њ | С Keys: A | D Тастери: А | Д NumPad: KP_8 | KP_2 Број.Тастатура: КП_8 | КП_2 NumPad: KP_4 | KP_6 Број.Тастатура: КП_4 | КП_6 None Ништа Set the value to use as the limit for an axis. Useful for a worn out analog stick. Постави ову вредност као граничну за правац. Употребљиво у раду са истрошеним аналогним управљачем. Negative Half Throttle Полу-регулатор умањења Positive Half Throttle Полу-регулатор увећавања Haptic Trigger: Name: Назив: Specify the name of an axis. Одредите Назив осе(правца). Mouse Settings Поставке миша Set the value of the dead zone for an axis. Подеси вредност мртве области за правaц. Presets: Поставке: Dead Zone: Мртва област: Max Zone: Највиша област: [NO KEY] [Без тастера] Throttle setting that determines the behavior of how to interpret an axis hold or release. Поставке регулатора које одређују понашање при тумачењу држи („hold“) или пусти („release“) за правац. Negative Throttle Регулатор умањења Normal Нормално Positive Throttle Регулатор увећавања Current Value: Текућа вредност: Set Постави Set %1 Скуп %1 Left Mouse Button Леви тастер миша Right Mouse Button Десни тастер миша Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog Прозорче To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Да би сте створили ново придруживање, притисните неко од дугмади тастатуре или кликните мишем на неко дугме у неком од језичака „Тастатура“ или „Миш“ Placeholder Препознавач положаја Toggle Преклопник Enables a key press or release to only occur when a controller button is pressed. Омогућава да се догоди дугме „притисни“ или „пусти“, и то, само ако је дугме контролера притиснуто. Enables rapid key presses and releases. Turbo controller. Омогућава хитрије дугме „притисни“ или дугме „пусти“. Контролер набуџивања. Turbo Набуџи Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Last keyboard/mouse button: Slots Слотови Na&me: Назив: Specify the name of a button. Унесите назив за дугме. Action: Радња: Specify the action that will be performed in game while this button is being used. Одредите радњу која ће се извршавати при употреби овог дугмета. Advanced Напредно Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel Текст-натпис X 4 gain offset Y 1 Start calibration Close Reset settings Save Сачувај Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Особине откривеног прозора Information About Window Подаци о прозору Class: Класа: TextLabel Текст-натпис Title: Наслов: Path: Путања: Match By Properties Прилагоди по Class класи Title наслову Path путањи Full Path Пуна путања File Name Назив датотеке DPadContextMenu Mouse (Normal) Миш (обично) Mouse (Inverted Horizontal) Миш (обрнуто водоравно) Mouse (Inverted Vertical) Миш (обрнуто усправно) Mouse (Inverted Horizontal + Vertical) Миш (обрнуто водоравно и усправно) Arrows Стрелице Keys: W | A | S | D Тастери: Њ | А | С | Д NumPad Број.тастатура None Ништа Standard Уобичајено Eight Way Осмосмерно 4 Way Cardinal Уобичајено четворосмерно 4 Way Diagonal Четворосмерно-дијагонално Mouse Settings Поставке миша DPadEditDialog Dialog Прозорче Presets: Поставке: Mouse (Normal) Миш (нормално) Mouse (Inverted Horizontal) Миш (обрнуто водоравно) Mouse (Inverted Vertical) Миш (обрнуто усправно) Mouse (Inverted Horizontal + Vertical) Миш (обрнуто водоравно и усправно) Arrows Стрелице Keys: W | A | S | D Тастери: Њ | А | С | Д NumPad Бројчана тастатура None Ништа Dpad Mode: Употреба Д-тастера: &Name: 4 Way Cardinal Уобичајено четворосмерно 4 Way Diagonal Четворосмерно-дијагонално DPad Delay: Д-тастери — кашњење: Time lapsed before a direction change is taken into effect. Кашњење пре но промена смера приметно наступи. s с Specify the name of a dpad. Унесите назив за Д-тастер. Mouse Settings Поставке миша Standard Уобичајено Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Осмосмерно Set Подеси Set %1 Скуп %1 EditAllDefaultAutoProfileDialog Default Profile Подразумеван профил Profile: Профил: Browse Разгледај Open Config Отвори подешавања Profile file path is invalid. Путања до датотеке профила није ваљана. ExtraProfileSettingsDialog Extra Profile Settings Додатна подешавања профила Key Press Time: Време притиска тастера: 0.00 ms 0.00 мс Profile Name: Назив профила: s сек. GameController Game Controller Контролер програма GameControllerDPad DPad Д-тастер GameControllerMappingDialog Game Controller Mapping Придруживач тастера контролера <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A 3 B 2 X 4 Y 1 Back Назад Start Почни Guide Водич Left Shoulder Леви окидач 1 Right Shoulder Десни окидач 1 Left Stick Click Притисак на леви управљач Right Stick Click Притисак на десни управљач Left Stick X Леви управљач — водоравно Left Stick Y Леви управљач — усправно Right Stick X Десни управљач — водоравно Right Stick Y Десни управљач — усправно Left Trigger Леви окидач 2 Right Trigger Десни окидач 2 DPad Up Д-тастер — Горе DPad Left Д-тастер — Лево DPad Down Д-тастер — Доле DPad Right Д-тастер — Десно Mapping Придруживања SDL 2 Game Controller Mapping String СДЛ-2 ниска придруживања тастера контролера Last Axis Event: Задњи догађај на правцу: Current Axis Detection Dead Zone: Откривање мртве области текућег правца: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Придруживач тастера контролера (%1) (#%2) Discard Controller Mapping? Поништавање придруживања контролера? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. Да ли да поништим придруживања за овај контролер? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Назад Guide Водич Start Почни LS Click Притисак 1. левог окидача RS Click Притисак 1. десног окидача L Shoulder 1. леви окидач R Shoulder 1. десни окидач L Trigger 2. леви окидач R Trigger 2. десни окидач GameControllerTrigger Trigger Окидач JoyAccelerometerButton Up Down Left Лево Right Десно Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis Правац JoyAxisButton Negative Умањи Positive Увећај Unknown Непознато Button Дугме JoyAxisContextMenu Mouse (Horizontal) Миш (водоравно) Mouse (Inverted Horizontal) Миш (обрнуто водоравно) Mouse (Vertical) Миш (усправно) Mouse (Inverted Vertical) Миш (обрнуто усправно) Arrows: Up | Down Стрелице: Горе | Доле Arrows: Left | Right Стрелице: Лево | Десно Keys: W | S Тастери: Њ | С Keys: A | D Тастери: А | Д NumPad: KP_8 | KP_2 Број.Тастатура: КП_8 | КП_2 NumPad: KP_4 | KP_6 Број.Тастатура: КП_4 | КП_6 None Ништа Mouse Settings Поставке миша Left Mouse Button Леви тастер миша Right Mouse Button Десни тастер миша JoyButton Processing turbo for #%1 - %2 Буџим за #%1 - %2 Finishing turbo for button #%1 - %2 Завршено набуџивање тастера #%1 - %2 Distance change for button #%1 - %2 Промена раздаљине за тастер #%1 - %2 Button Тастер [NO KEY] [Без тастера] [Set %1 1W] [Скуп %1 1-смерно] [Set %1 2W] [Скуп %1 2-смерно] [Set %1 WH] [Скуп %1 WH] JoyButtonContextMenu Toggle Преклопи Turbo Набуџи Clear Очисти Set Select Одабир скупа Disabled Онемогућено Set %1 Скуп %1 Set %1 1W Скуп %1 1-смерно Set %1 2W Скуп %1 2-смерно Set %1 WH Скуп %1 WH JoyButtonSlot Mouse Миш Up Напред Down Назад Left Лево Right Десно LB Л.дугме MB С.дугме RB Д.дугме Pause Пауза Hold Држи Cycle Врти Distance Раздаљина Release Пусти Mouse Mod Мишар Press Time Трајање притиска Delay Кашњење Load %1 Учитај %1 Set Change %1 Измена скупа %1 [Text] %1 [Текст] %1 [Exec] %1 [Извршавам] %1 [NO KEY] [Без тастера] JoyControlStick Stick Управљач JoyControlStickButton Up Напред Down Назад Left Лево Right Десно Button Дугме JoyControlStickContextMenu Mouse (Normal) Миш (обично) Mouse (Inverted Horizontal) Миш (обрнуто водоравно) Mouse (Inverted Vertical) Миш (обрнуто усправно) Mouse (Inverted Horizontal + Vertical) Миш (обрнуто водоравно и усправно) Arrows Стрелице Keys: W | A | S | D Тастери: Њ | А | С | Д NumPad Број.тастатура None Ништа Standard Уобичајено Eight Way Осмосмерно 4 Way Cardinal Уобичајено четворосмерно 4 Way Diagonal Четворосмерно-дијагонално Mouse Settings Поставке миша JoyControlStickEditDialog Dialog Прозорче X: X: 0 0 Y: Y: Distance: Раздаљина: Presets: Поставке: Mouse (Normal) Миш (обично) Mouse (Inverted Horizontal) Миш (обрнуто водоравно) Mouse (Inverted Vertical) Миш (обрнуто усправно) Mouse (Inverted Horizontal + Vertical) Миш (обрнуто водоравно и усправно) Arrows Стрелице Keys: W | A | S | D Тастери: Њ | А | С | Д NumPad Бројчана тастатура None Ништа Stick Mode: Начин рада управљача: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Уобичајено: 8-смерни управљач са два притиснута тастера за померање по дијагонали. Осмосмерно: 8-смерни управљач са сопственим тастерима за сваки смер. У једном тренутку, радни је само један тастер. Употребљиво за роголике (енг. „rougelike“) игре. Уобичајено 4-смерно: 4-смерни управљач за померање у 4 смера (померена за 90°). Употребљиво за изборнике. 4-смерно дијагонално: 4-смерни управљач где свака област одговара дијагоналној области датог управљача. 4 Way Cardinal Уобичајено четворосмерно 4 Way Diagonal Четворосмерно-дијагонално Modifier Zone: Dead zone value to use for an analog stick. Вредност мртве области код аналогних управљача. Value when an analog stick is considered moved 100%. Вредност у којој је аналогни управљач у крајњем положају. The area (in degrees) that each diagonal region occupies. Област (у степенима) коју свака област на дијагонали заузима. Square Stick: Четвртаст управљач: Percentage to modify a square stick coordinates to confine values to a circle Постотак промене квадратних координата управљача за ограничавање вредности у кружници % % Stick Delay: Кашњење управљача: Time lapsed before a direction change is taken into effect. Кашњење пре но промена смера приметно наступи. s с Modifier: Измењивач: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Дугме за уређивање који је радно док управљач ради. Употребљиво за доделе области тастерима-измењивачима који могу да се употребе за додавање могућности ходај-трчи аналогним управљачима. PushButton Дугме Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Назив: Specify the name of an analog stick. Унесите назив за аналогни управљач. Mouse Settings Поставке миша Standard Уобичајено Bearing: Азимут: % Safe Zone: % Безбедна област: Eight Way Осмосмерно Dead Zone: Мртва област: Max Zone: Највиша област: Diagonal Range: Дијагонални опсег: Set Постави Set %1 Скуп %1 JoyControlStickModifierButton Modifier Измењивач JoyDPad DPad Д-тастер JoyDPadButton Up Горе Down Доле Left Лево Right Десно Button Дугме JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button JoySensorContextMenu Mouse Settings Поставке миша JoySensorEditDialog Dialog Прозорче 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Безбедна област: Presets: Поставке: Dead Zone: Мртва област: Dead zone value to use for an analog sensor. Max Zone: Највиша област: Value when an analog sensor is considered moved 100%. Diagonal Range: Дијагонални опсег: The area (in degrees) that each diagonal region occupies. Област (у степенима) коју свака област на дијагонали заузима. Sensor Delay: Time lapsed before a direction change is taken into effect. Кашњење пре но промена смера приметно наступи. s с Na&me: Назив: Specify the name of an analog sensor. Mouse Settings Поставке миша Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set %1 Скуп %1 JoySensorPreset None Ништа Mouse (Normal) Mouse (Inverted Horizontal) Миш (обрнуто водоравно) Mouse (Inverted Vertical) Миш (обрнуто усправно) Mouse (Inverted Horizontal + Vertical) Миш (обрнуто водоравно и усправно) Arrows Стрелице Keys: W | A | S | D Тастери: Њ | А | С | Д NumPad JoyTabWidget <New> <Ново> Battery level of controller Remove Уклони Remove configuration from recent list. Уклони подешавање са текуће листе. Load Учитај Load configuration file. Учитај датотеку са подешавањима. Save Сачувај Save changes to configuration file. Сачувај измене у датотеку подешавања. Save As Сачувај као Save changes to a new configuration file. Сачувај измене у новој датотеци подешавања. Sets Скупови Copy from Set Умножи из ... Settings Постави називе Set 1 1. скупа Set 2 2. скупа Set 3 3. скупа Set 4 4. скупа Set 5 5. скупа Set 6 6. скупа Set 7 7. скупа Set 8 8. скупа Stick/Pad Assign Придружи Управљач/Тастатуру Controller Mapping Придруживач тастера контролера Quick Set Брзе поставке Names Називи Toggle button name displaying. Приказивање назива преклопника. Pref Опште поставке Change global profile settings. Измените опште поставке профила. Reset Поништи Revert changes to the configuration. Reload configuration file. Поништи измене и учитај опет датотеку са подешавањем. Open Config Отвори подешавања Config Files (*.amgp *.xml) Датотеке подешавања (*.amgp *.xml) Config File (*.%1.amgp) Датотека подешавања (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Да ли да сачувам измене профила? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Имате несачуваних промена новог профила. Да ли желите да их сачувам или да их поништим? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Имате несачуваних промена у профилу "%1" . Да ли желите да их сачувам или да их поништим? Sticks Управљачи Sensors DPads Д-тастери No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Нема придруживања за дугмад. Можете да употребите „Брзе поставке“ за придруживања дугмадима или да искључите скривање „празних“ дугмади. Set %1: %2 Скуп %1: %2 Set %1 Скуп %1 Copy Set Assignments Умножи придруживања из скупа Are you sure you want to copy the assignments and device properties from %1? Да ли заиста желите да умножите придруживања и особине уређаја из %1? Save Config Сачувај подешавања Set Постави Joystick Joystick Џојстик JoystickStatusWindow Properties Особине Details Детаљи Name: Назив: %1 %1 Number: Број: Axes: Праваца: Buttons: Дугмад: Hats: Капице: Sensors: Battery: Unknown Непознато GUID: ЈИБГ: Game Controller: Контролер за игре: Axes Правци Buttons Дугмад Hats Капице Sensors %1 (#%2) Properties %1 (#%2) Особине Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None Ништа Axis %1 Правац %1 Hat %1 Хат %1 No Не Yes Да MainSettingsDialog Edit Settings Уређивање поставки General Опште поставке Controller Mappings Придруживања контролера Language Језик Auto Profile Ауто-профил Mouse Миш Advanced Напредно <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Постављање уобичајеног директоријума за учитавање постојећих или чување нових профила.</p></body></html> Recent Profile Count: Број скорашњих профила: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Број профила који се може сместити у листу недавно употребљаваних профила. Број 0 означава приказ свих употребљаваних профила.</p></body></html> Gamepad Poll Rate: Провера порука џојстика након: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Измените време након кога ће програм да провери да ли је гејмпед производио догађаје (поруке). Уобичајена вредност је 10 мс. Ниже вредности ове опције могу да доведу до веће употребе ЦПЈ (процесора), Проверите ову поставку пре озбиљније употребе. Hide main window when the main window close button is clicked instead of quitting the program. Притиском на дугме затварања главног прозора, он се затвара али програм остаје покренут у обавештајној зони. Close To Tray Смести у обавештајну зону Have Windows start AntiMicroX at system startup. Покрени програм са покретањем система. Launch At Windows Startup Покрени по покретању система Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Приказаће се скорашњи профили за све контролере као јединствен списак профила у обавештајној зони. Уобичајено је употреба под-изборника. Single Profile List in Tray Јединствен списак профила у обавештајној зони Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Програм ће се сместити у траку покренутих задатака. Подразумевано смештање програма је у обавештајној зони ако је она доступна. Minimize to Taskbar Смести у траку покренутих задатака This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Ако је укључена ова опција, програм ће скрити дугмад која немају придружених слотова. У прозору „Брзе поставке“ моћи ћете да подесите придруживања тастера гејмпеда. Hide Empty Buttons Сакриј „празну“ дугмад When the program is launched, open the last known profile that was opened during the previous session. Ово омогућава да се по покретању програма учита познат, последње учитаван профил у претходној сесији. Auto Load Last Opened Profile Отвори сам последњи употребљени профил Only show the system tray icon when the program first launches. Приказује само икону у обавештајној зони по првом покретању програма. Launch in Tray Покрени у обавештајној зони Associate .amgp files with AntiMicroX in Windows Explorer. Придружуј „.amgp“-датотеке програму Анти-микро (виндоуз експлорер). Associate Profiles Придружени профили Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Show low battery notification Show empty battery notification Key Repeat Вишеструки притисци тастера Active keys will be repeatedly pressed when this option is enabled. Ако је укључено омогућени су вишеструки, узастопни притисци тастера. Enable Омогућено Specifies how much time should elapse before key repeating begins. Кашњење пре започињања вишеструког, узастопног притискања тастера. Specifies how many times key presses will be performed per seconds. Одређује број притисака тастера у секунди код вишеструког, узастопног притискања тастера. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>Сарадници аутора су локализовали програм за разне језике. Уобичајено, програм ће употребљавати језичке поставке самог система за приказ, али, уколико то желите, можете употребљавати програм и на језику који одаберете на листи испод.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Ништа Error Warning Info Подаци Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Поништи Class класи Title наслову Program Програм Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Искључи виндоуз-поставку за „побољшање прецизности показивача“ док програм ради. Онемогућавањем ове виндоуз-поставке повећава се прецисност померања показивача (миша) у самом програму. Disable Enhance Pointer Precision Искључи побољшања прецизности показивача Smoothing Углађеност Refresh Rate: Брзина освежавања: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Брзина освежавања представља протекло време између догађаја миша. Будите врло опрезни при уређивању ове поставке јер се може повећати употреба ЦПЈ (процесора), а при премалим вредностима ове поставке систем може да пређе у нестабилно стање. Проверите ову поставку пре озбиљније употребе. Spring Скоковито Screen: Екран: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Употребљава наведени екран за „скоковит“ режим. Уобичајено, На ГНУ-Линуксу је употреба основног екрана, а на Виндоузу свих расположивих екрана. Accel Numerator: Бројилац убрзања: 0 0 Accel Denominator: Именилац убрзања: Accel Threshold: Праг убрзања: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Када су вредности убрзања патвореног миша измењене од стране различитих процеса, посебно при изласку из старијих игара, можете пожелети да вратите ове вредности убрзања патвореног миша на оне претходне. Reset Acceleration Поврати убрзање Delay: Кашњење: Pro&file Directory: ms мс Rate: Брзина: times/s пута/сек. Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. Испод је листа сачуваних, прилагођених мапирања. Можете да употребите следећу табелу да бисте избрисали мапирања или да их привремено онемогућите. Можете да онемогућите мапирања која су укључена у СДЛ; само уметните нови ред са одговарајућим ЈИБГ-џојстика и означите онемогући. Подешавања се неће узети у обзир док се не освежи листа доступних џојстика или док не искључите дати, конкретан џојстик. GUID ЈИБГ Mapping String Ниска придруживања Disable? Искључи? Delete Уклони Default подразумевано English енглески Active Омогућен Devices: Уређаји: All Сви Device Уређај Profile Профил Default? Подразумевано? Add Додај Edit Уреди AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Такође, Виндоуз корисници који желе да употребе нижу вредност, нека провере и „Искључи побољшања прецизности показивача“, ако нису онемогућили ову опцију у самом систему. Select Default Profile Directory Одабир уобичајеног директоријум профила Are you sure you want to delete the profile? Да ли заиста желите да уклоните овај профил? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu Нисам пронашао џојстик. Када га прикључите покрените „Поставке > Пронађи џојстике“ из главног менија If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Датотека &Options П&оставке AntiMicroX Анти-микро He&lp &Quit &Затвори Ctrl+Q Ctrl+Q &Update Joysticks Про&нађи џојстике Ctrl+U Ctrl+U &Hide &Сакриј Ctrl+H Ctrl+H &About О прогр&аму Ctrl+A Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page Матична страна (%1) (%1) Open File Отвори датотеку Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore В&рати Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Покрени као администратор? Failed to elevate program Не могу да покренем програм Failed to restart this program as the Administrator Неуспело покретање програма са админ. дозволама MouseAxisSettingsDialog Mouse Settings - Поставке миша - Set %1 Скуп %1 MouseButtonSettingsDialog Mouse Settings - Поставке миша - Set %1 Скуп %1 MouseControlStickSettingsDialog Mouse Settings Поставке миша Set %1 Скуп %1 MouseDPadSettingsDialog Mouse Settings Поставке миша Set %1 Скуп %1 MouseSensorSettingsDialog Mouse Settings Поставке миша Set %1 Скуп %1 MouseSettingsDialog Mouse Settings Поставке миша Mouse Mode: Мишар: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. У начину „показивач“, омогућава се релативно померање показивача миша у односу на његову текућу позицију. У „скоковитом“ начину померање показивача миша је од средишта екрана у свим смеровима, а када се показивач миша нађе у мртвој области програм га враћа на средину екрана. Cursor Показивач Spring Скоковито Acceleration: Убрзавање: Enhanced Precision Побољшана прецизност Linear Линеарно Quadratic Квадратно Cubic Кубно Quadratic Extreme Набуџено квадратно Power Function Нај-функција Easing Quadratic Квадратно попуштање Easing Cubic Кубно попуштање Mouse Speed Settings Брзина померања Enable to change the horizontal and vertical speed boxes at the same time. Омогућује истовремену промену брзине у оба правца. Change Together Измењуј повезано Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps 1 = 20 тачака/сек. Wheel Hori. Speed: Tочкић водоравно: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Постављање брзине водоравног померања миша према одговарајућем, симулираном броју зареза по секунди. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Постављање брзине усправног померања миша према одговарајућем, симулираном броју зареза по секунди. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. За кривуљу убрзавања Нај-функције. Одређује чинилац код постављања осетљивости кривуље. За вредност изнад 1.0, покрети миша ће се више убрзавати у крајњем доњем положају осе. Easing Duration: Трајање попуштањa: s с Highest value to accelerate mouse movement by Највиша вредност за убрзање померања миша x x Start %: Почетак %: Acceleration begins at this percentage of the base multiplier Убрзање почиње након оволико процената од основног чиниоца Minimum amount of axis travel required for acceleration to begin Најмања количина осног померања неопходна за отпочињање убрзања Max Threshold: Највећи праг: Maximum axis travel before acceleration has reached the multiplier value Највиша количина осног померања пре но се достигне вредност датог чиниоца E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Пречник пуштања: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Одређује да ће „скоковито“ подручје бити релативно у односу на положај миша постављен не-релативним скоком. Relative Релативно Mouse Status Стање миша X: X: 0 (0 pps) 0 (0 тачака/сек) Y: Y: 1 = 1 notch(es)/s 1 = 1 зарез(а)/сек. Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Подиже брзину померања миша 1,5 пута по достизању 95% осног пута Побољшана прецизност: Трослојна кривуља која чини да померање миша буде споро на доњем крају осе и брзо на њеном горњем крају. Линеарно: Померања миша је сразмерно по оси. Квадратно: Померања миша се лагано убрзавају на доњем крају. Кубно: Спорије убрзавање миша од „Квадратног“. Набуџено квадратно: Подиже брзину померања миша 1,5 пута по достизању 95% од могућег осног померања. Нај-функција: Дозвољава потпуније прилагођавање кривуље убрзавања. Квадратно попуштање: У горњем крају осе, постепено убрзање током времена употребљавајући квадратну кривуљу. Кубно попуштање: У горњем крају осе, постепено убрзање током времена употребљавајући кубну кривуљу. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Tочкић усправно: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. Одређује количину времена (у секундама) неопходну за потпуно убрзање миша, а након достизања горњег краја осе. % % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Продужује време за које ће се применити додатно убрзање. У обзир ће се узети осно померање. Спорији „флик“ смањује стварно време након кога ће се примењивати додатно убрзање. Spring Settings Скоковито померање Spring Width: По ширини: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Мењање ширине области за померање показивача у скоковитом начину. „0“ означава искоришћавање укупне ширине Вашег екрана. Spring Height: По висини: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. Мењање висине области за померање показивача у скоковитом начину. „0“ означава искоришћавање укупне висине Вашег екрана. %n notch(es)/s %n зарез/сек. %n зареза/сек. %n зареза/сек. QKeyDisplayDialog Key Checker Провера тастера тастатуре <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Руковалац догађајем: Native Key Value: Очитана вредност: 0x00000000 0x00000000 Qt Key Value: КјуТ вредност: antimicro Key Value: QObject Super Супер Menu Изборник Mute Мук Vol+ Гласније Vol- Тише Play/Pause Пусти/Пауза Play Пусти Pause Пауза Prev Претходно Next Наредно Mail Е-пошта Home Почетно Media Медији Search Нађи Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program Излазак из програма # of joysticks found: %1 # џојстика пронађено: %1 List Joysticks: Списак џојстика: --------------- --------------- Joystick %1: Џојстик %1: Attempting to use fallback option %1 for event generation. Покушавам да користим резервну опцију %1 у стварању догађаја. Failed to open event generator. Exiting. Не могу да отворим ствараоца догађаја. Излазим. Using %1 as the event generator. Употребљавам %1 као ствараоца догађаја. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Unknown log level: Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Путања до профила „%1“ није ИксМЛ датотека. Profile location %1 does not exist. Путања до профила „%1“ не постоји. Controller identifier is not a valid value. Означивач контролера нема ваљану вредност. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. Није одређен број скупа. An invalid event generator was specified. Одређен је неважећи стваралац догађаја. No event generator string was specified. Није одређен назив ствараоца догађаја. No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Издање проширење „xinput“ је старије од издања 2.0. Нису могуће измене брзина при руковању мишем. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set Брзе поставке <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>Притисните неки тастер или померите управљач на уређају <br/>„%1“ (<span style=" font-weight:600;">%2</span>). Након тога, појавиће се прозорче <br/>у којем ћете моћи да придружите том тастеру-управљачу <br/>одговарајући тастер тастатуре, догађај и сл.</p></body></html> Quick Set %1 Брзе поставке — %1 SetAxisThrottleDialog Throttle Change Промена регулатора The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? Поставке регулатора за правац %1 су се промениле. Желите ли да ове промене регулатора буду доступне у свим групама? SetJoystick Set %1: %2 Скуп %1: %2 Set %1 Скуп %1 SetNamesDialog Set Name Settings Поставке назива скупова Set 1 1. скуп Set 2 2. скуп Set 3 3. скуп Set 4 4. скуп Set 5 5. скуп Set 6 6. скуп Set 7 7. скуп Set 8 8. скуп Name Назив SimpleKeyGrabberButton Mouse Миш SpringModeRegionPreview Spring Mode Preview Преглед за начин „Скоковито“ UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Не могу да нађем ваљану „uinput“-датотеку уређаја. Проверите да ли је „uinput“-модул учитан. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Не могу да отворим „uinput“-датотеку уређаја Проверите да ли имате дозволу за уписивање на уређај Using uinput device file %1 Употребљавам „uinput“-датотеку уређаја %1 UInputHelper a а b б c ц d д e е f ф g г h х i и j ј k к l л m м n н o о p п q љ r р s с t т u у v в w њ x џ y ж z з Esc Врати („Esc“) F1 Ф1 F2 Ф2 F3 Ф3 F4 Ф4 F5 Ф5 F6 Ф6 F7 Ф7 F8 Ф8 F9 Ф9 F10 Ф10 F11 Ф11 F12 Ф12 F13 Ф13 F14 Ф14 F15 Ф15 F16 Ф16 F17 Ф17 F18 Ф18 F19 Ф19 F20 Ф20 F21 Ф21 F22 Ф22 F23 Ф23 F24 Ф24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace Уназад Tab Таб [ [ ] ] \ \ CapsLock В.слова ; ; ' ' Enter Унеси Shift_L л.Мењач , , . . / / Ctrl_L л.Ктрл Super_L л.Супер Alt_L л.Алт Space Размакница Alt_R д.Алт Menu Изборник Ctrl_R д.Ктрл Shift_R д.Мењач Up Горе Left Лево Down Доле Right Десно PrtSc Сликај Ins Уметни Del Бриши Home Почетак End Крај PgUp Страна изнад PgDn Страна испод NumLock УКЉ/ ИСКЉ * * + + KP_Enter КП_Унеси KP_1 КП_1 KP_2 КП_2 KP_3 КП_3 KP_4 КП_4 KP_5 КП_5 KP_6 КП_6 KP_7 КП_7 KP_8 КП_8 KP_9 КП_9 KP_0 КП_0 SCLK SCLK Pause Пауза Super_R д.Супер Mute Мук VolDn Тише VolUp Гласније Play Пусти Stop Заустави Prev Претходно Next Наредно [NO KEY] [Без тастера] UnixWindowInfoDialog Captured Window Properties Особине откривеног прозора Information About Window Подаци о прозору Class: Класа: TextLabel Текст-натпис Title: Наслов: Path: Путања: Match By Properties Прилагоди по Class класи Title наслову Path путањи VDPad VDPad Патворен Д-тастер VirtualKeyPushButton Space Размакница Tab Таб Shift (L) л. Мењач Shift (R) д. Мењач Ctrl (L) л. Ктрл Ctrl (R) д. Ктрл Alt (L) л. Алт Alt (R) д. Алт Alt Gr ` ` ~ ~ - - = = [ [ ] ] \ \ Caps В.слова ; ; ' ' , , . . / / ESC Врати PRTSC Сликај SCLK SCLK INS Уметни PGUP Страна изнад DEL Бриши PGDN Страна испод 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK УКЉ/ ИСКЉ * * + + Enter Унеси Del Бриши < < : : Super (L) л.Супер Menu Избор Up Горе Down Доле Left Лево Right Десно VirtualKeyboardMouseWidget Keyboard Тастатура Mouse Миш Mouse Settings Поставке миша Left Mouse Лево Up Mouse Горе Left Button Mouse Леви тастер Middle Button Mouse Средњи тастер Right Button Mouse Десни тастер Wheel Up Mouse Точкић унапред Wheel Left Mouse Точкић улево Wheel Right Mouse Точкић удесно Wheel Down Mouse Точкић уназад Down Mouse Доле Right Mouse Десно Button 4 Mouse Тастер 4 Mouse 8 Mouse Миш 8 Button 5 Mouse Тастер 5 Mouse 9 Mouse Миш 9 NONE НИШТА [NO KEY] [Без тастера] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Програми Browser Back Претходно (веб прегледник) Browser Favorites Обележивачи (веб прегледник) Browser Forward Наредно (веб прегледник) Browser Home Почетна страна (веб прегледник) Browser Refresh Освежи (веб прегледник) Browser Search Претрага (веб прегледник) Browser Stop Заустави учитавање (веб прегледник) Calc Калкулатор Email Е-пошта F13 Ф13 F14 Ф14 F15 Ф15 F16 Ф16 F17 Ф17 F18 Ф18 F19 Ф19 F20 Ф20 F21 Ф21 F22 Ф22 F23 Ф23 F24 Ф24 Media Медији Media Next Медији — Наредно Media Play Медији — Пусти Media Previous Медији — Претходно Media Stop Медији — Заустави Search Нађи Volume Down Тише Volume Mute Мук Volume Up Гласније VirtualMousePushButton INVALID ОШТЕЋЕНО WinAppProfileTimerDialog Capture Application Разоткриј прозор After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. По притиску дугмета „Разоткриј прозор“, одаберите прозор програма који желите да повежете са профилом. Разоткривање тог прозора отпочеће након истека доле задатог времена. Timer: Након: Seconds секунди(е,а) Cancel Поништи WinExtras [NO KEY] [Без тастера] AntiMicro Profile X11Extras ESC Врати Tab Таб Space Размакница DEL Бриши Return Унеси („Return“) („Enter“) KP_Enter КП_Унеси Backspace Уназад Alt Gr xinput extension was not found. No mouse acceleration changes will occur. Није нађено проширење „xinput“. Нису могуће измене брзина при руковању мишем. xinput version must be at least 2.0. No mouse acceleration changes will occur. Издање проширење „xinput“ је старије од издања 2.0. Нису могуће измене брзина при руковању мишем. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Није нађено „НPtrFeedbackClass“ за патворени показивач. Нису могуће измене брзина при руковању мишем за уређај чији је ИБ=%1 Changing mouse acceleration for device with id=%1 Измена убрзања при употреби миша за уређај чији је ИБ=%1 XMLConfigReader Could not write updated profile XML to file %1. Не могу да упишем зановљен ИксМЛ-профил у датотеку %1. XMLConfigWriter Could not write to profile at %1. Не могу да уписујем у профил у %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Покреће програм само у обавештајној зони. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_sv.ts000066400000000000000000013236731471077622000274260ustar00rootroot00000000000000 AboutDialog About Om Version Version Info Information Changelog Ändringslogg Credits AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development Om utvecklingen "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Copyright: 2013 - 2022 License Licens Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 Använder händelsehanterare: %1 AddEditAutoProfileDialog Auto Profile Dialog Dialogfönster för automatisk profil Pro&file: Pro&fil: Browse Bläddra Window: Fönster: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Välj Fönster. Klicka på lämplig applikationsfönster och applikationssökvägen kommer att fyllas i i formuläret. Detect Window Properties Upptäck fönsteregenskaper &Class: &Klass: T&itle: T&itel: set partial title ange deltitel Application: Applikation: Select Välj De&vices: Enhe&ter: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Välj den här profilen som standardinläst för den angivna enheten. Valet kommer att användas i stället för alla standardprofiler. Set as Default for Controller Ange som standard för handkontroll A different profile is already selected as the default for this device. En annan profil har redan valts som standardprofil för den här enheten. Current (%1) Aktuell (%1) Open Config Öppna konfigurationen Select Program Välj program Programs (*.exe) Program (*.exe) Please use the main default profile selection. Använd det huvudsakliga standardprofilvalet. Main Profile Huvudprofil Already selected Redan vald Chosen Profile Vald profil The selection will be used instead of the all default profile option. Valet kommer att användas i stället för alla standardprofiler. Please select a window by using the mouse. Press Escape if you want to cancel. Välj ett fönster med musen. Tryck på Escape om du vill avbryta. Capture Application Window Fånga applikationsfönster Could not obtain information for the selected window. Det gick inte att hämta information för det valda fönstret. Application Capture Failed Misslyckades med att fånga applikationen Profile file path is invalid. Sökvägen till profilfilen är ogiltig. No window matching property was specified. Program path is invalid or not executable. Programsökvägen är ogiltig eller inte körbar. File is not an .exe file. Filen är inte en .exe-fil. No window matching property was selected. AdvanceButtonDialog Advanced Avancerad Assignments Uppgifter Toggle Växla Turbo Turbo Set Selector Blank or KB/M Blank eller KB/M Hold Håll Pause Paus Cycle Distance Avstånd Insert Infoga Delete Ta bort Clear All Rensa alla Time: Tid: 0.01s 0.01s 0s 0s Insert a pause that occurs in between key presses. Infoga en paus mellan tangenttryckningarna. Release Släpp Insert a new blank slot. Infoga en ny tom plats. Delete a slot. Ta bort en plats. Clear all currently assigned slots. Rensa alla tilldelade platser. Specify the duration of an inserted Pause or Hold slot. Ange varaktigheten för en infogad paus- eller hållplats. 0m 0m &Mouse Speed Mod: &Mushastighetsmod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: Avstånd: % % Mouse Mod Musmod Press Time Trycktid Delay Fördröjning Execute Utför Load Ladda Set Change Text Entry Join Sammanfoga Split Dela Placeholder Platshållare 0 0 Set the percentage that mouse speeds will be modified by. Ställ in den procentandel som mushastigheterna kommer att ändras med. Auto Reset Cycle After Automatisk återställning av cykel efter seconds sekunder Executable: Körbar: ... ... Arguments: Argument: Enabled Aktiverad Mode: Läge: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Normal Gradient Lutning Pulse Puls Delay: Fördröjning: 0.10s 0.10s Rate: Hastighet: 10.0/s 10.0/s Disabled Inaktiverad Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] [INGEN TANGENT] sec. sek. /sec. /sek. Not checked slots Ej markerade platser To delete slots, you need to select at least one För att ta bort platser måste du välja minst en To insert slots, you need to select at least one För att infoga platser måste du välja minst en Unknown current slot Okänd aktuell plats Click on chosen slots before joining them Klicka på valda platser innan du sammanfogar dem Not enough slots Inte tillräckligt med platser It's impossible to join slots. Add at least one other slot. Det är omöjligt att sammanfoga platser. Lägg till minst en annan plats. Not selected slots Ej valda platser It's impossible to join slots. Select at least two slots before joining them Det är omöjligt att sammanfoga platser. Välj minst två platser innan de sammanfogas Only keyboard slots Endast tangentbordsplatser It's only possible to join simple and mix keyboard slots Det är endast möjligt att sammanfoga enkla och mixade tangentbordsplatser It's impossible to split slots. Add at least one other slot. Det är omöjligt att dela platser. Lägg till minst en annan plats. Not selected slot Ej valda platser Select your slot before splitting. Välj din plats innan den delas. Too many mix slots För många mixade platser Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: Y Axis: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Down: Left: Right: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Haptic Trigger: Name: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Dead Zone: Max Zone: [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Attach the numeric keypad Last keyboard/mouse button: Slots Na&me: Specify the name of a button. Action: Specify the action that will be performed in game while this button is being used. Advanced Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel TextLabel X X gain offset Y Y Start calibration Close Reset settings Save Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAccelerometerButton Up Up Down Down Left Left Right Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Negative Positive Unknown Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Up Down Left Right LB MB RB Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] JoyControlStick Stick JoyControlStickButton Up Down Left Right Button JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: 0 Y: Distance: Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Down Left Right Button JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Button JoySensorContextMenu Mouse Settings Mouse Settings JoySensorEditDialog Dialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Safe Zone: Presets: Presets: Dead Zone: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: Diagonal Range: The area (in degrees) that each diagonal region occupies. The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Na&me: Na&me: Specify the name of an analog sensor. Mouse Settings Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None None Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad JoyTabWidget <New> Battery level of controller Remove Remove configuration from recent list. Load Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sensors DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Details Name: %1 Number: Axes: Buttons: Hats: Sensors: Battery: Unknown GUID: Game Controller: Axes Buttons Hats Sensors %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None None Axis %1 Hat %1 No Yes MainSettingsDialog Edit Settings General Controller Mappings Language Auto Profile Mouse Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Pro&file Directory: Show low battery notification Show empty battery notification Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID Mapping String Disable? Delete Default English Active Devices: All Device Profile Default? Add Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Options He&lp &Quit Ctrl+Q &Update Joysticks Ctrl+U &Hide Ctrl+H &About Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page (%1) Open File Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Failed to elevate program Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSensorSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Prev Next Mail Home Media Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name SimpleKeyGrabberButton Mouse SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 2 3 4 5 6 7 8 9 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK * + Enter Del < : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard Mouse Mouse Settings Left Mouse Up Mouse Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel WinExtras [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_tr.ts000066400000000000000000013063271471077622000274200ustar00rootroot00000000000000 AboutDialog About Hakkında Version Sürüm Info Bilgi Changelog Değişiklik Günlüğü Credits Katkıda Bulunanlar AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development Geliştirme Hakkında "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Telif Hakkı: 2013 - 2022 License Lisans Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 Olay giderici kullanılıyor: %1 AddEditAutoProfileDialog Auto Profile Dialog Profil Diyaloğu Hakkında Pro&file: Pro&fil: Browse Gözat Window: Pencere: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Pencere'yi seç. Doğru uygulamaya penceresine tıkladığında uygulama yolu formda doldurulmuş olacak. Detect Window Properties Pencere Özelliklerini Algıla &Class: &Sınıf: T&itle: B&aşlık: set partial title kısmi başlık ayarla Application: Uyuglama: Select Seç De&vices: Ci&hazlar: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Bu profili belirtilen cihaz için varsayılan olarak seçin. Bu seçim tüm varsayılan profil ayarlarının yerine kullanılır. Set as Default for Controller Oyun Kumandası için Varsayılan Olarak Ayarla A different profile is already selected as the default for this device. Bu cihaz için halihazırda varsayılan olarak bir profil seçili. Current (%1) Şu anda (%1) Open Config Yapılandırıcıyı Aç Select Program Program Seç Programs (*.exe) Programlar (*.exe) Please use the main default profile selection. Lütfen ana varsayılan profil seçimini kullanın. Main Profile Ana Profil Already selected Halihazırda seçili Chosen Profile Seçili Profil The selection will be used instead of the all default profile option. Diğer tüm profil ayarları yerine bu seçim kullanılacak. Please select a window by using the mouse. Press Escape if you want to cancel. Lütfen farenizi kullanarak bir pencere seçiniz. İptal etmek için Escape (ESC)'ye basınız. Capture Application Window Uygulama Penceresini Yakala Could not obtain information for the selected window. Seçili pencere için bilgi alınamadı. Application Capture Failed Uygulama Yakalaması Başarısız Oldu Profile file path is invalid. Profilin dosya yolu geçerli değil. No window matching property was specified. Hiçbir pencere eşleştirme özelliği belirtilmedi. Program path is invalid or not executable. Uygulama yolu geçersiz veya çalıştırılabilir değil. File is not an .exe file. Dosya, .exe dosyası değil. No window matching property was selected. Hiçbir pencere eşleştirme özelliği seçilmedi. AdvanceButtonDialog Advanced Assignments Toggle Turbo Set Selector Blank or KB/M Hold Pause Cycle Distance Insert Delete Clear All Time: 0.01s 0s Insert a pause that occurs in between key presses. Release Insert a new blank slot. Delete a slot. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. 0m &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: % Mouse Mod Press Time Delay Execute Load Set Change Text Entry Join Split Placeholder 0 Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After seconds Executable: ... Arguments: Enabled Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Delay: 0.10s Rate: 10.0/s Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] sec. /sec. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: Y Axis: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Down: Left: Right: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Haptic Trigger: Name: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Dead Zone: Max Zone: [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Unutmayın, bilgisayarınıza bağlı bir tuş takımınız yoksa veya masaüstü bilgisayarlardaki gibi gömülü değilse çalışmaz. Attach the numeric keypad Sayısal tuş takımını bağlayın Last keyboard/mouse button: Slots Na&me: Specify the name of a button. Action: Specify the action that will be performed in game while this button is being used. Advanced Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel MetinEtiketleri X X gain offset Y Y Start calibration Close Reset settings Save Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAccelerometerButton Up Yukarı Down Aşağı Left Sol Right Sağ Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Negative Positive Unknown Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Up Down Left Right LB MB RB Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] JoyControlStick Stick JoyControlStickButton Up Down Left Right Button JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: 0 Y: Distance: Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Down Left Right Button JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Tuş JoySensorContextMenu Mouse Settings Fare Ayarları JoySensorEditDialog Dialog Diyalog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Güvenli Alan: Presets: Önayarlar: Dead Zone: Ölü Alan: Dead zone value to use for an analog sensor. Max Zone: Maksimum Alan: Value when an analog sensor is considered moved 100%. Diagonal Range: Çapraz Menzil: The area (in degrees) that each diagonal region occupies. Her çapraz bölgenin kapladığı alan (derece cinsinden). Sensor Delay: Time lapsed before a direction change is taken into effect. Yön değişimi yapılmadan önce zaman aşımına uğrandı. s s Na&me: İs&im: Specify the name of an analog sensor. Mouse Settings Fare Ayarları Roll (°/s) Pitch (°/s) Yaw (°/s) Set Ayarla Set %1 Ayarla %1 JoySensorPreset None None Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad JoyTabWidget <New> Battery level of controller Remove Remove configuration from recent list. Load Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sensors DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Details Name: %1 Number: Axes: Buttons: Hats: Sensors: Battery: Unknown GUID: Game Controller: Axes Buttons Hats Sensors %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None None Axis %1 Hat %1 No Yes MainSettingsDialog Edit Settings General Controller Mappings Language Auto Profile Mouse Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Pro&file Directory: Show low battery notification Show empty battery notification Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID Mapping String Disable? Delete Default English Active Devices: All Device Profile Default? Add Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Options He&lp &Quit Ctrl+Q &Update Joysticks Ctrl+U &Hide Ctrl+H &About Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page (%1) Open File Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Failed to elevate program Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSensorSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Prev Next Mail Home Media Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name SimpleKeyGrabberButton Mouse SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 2 3 4 5 6 7 8 9 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK * + Enter Del < : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard Mouse Mouse Settings Left Mouse Up Mouse Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel WinExtras [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_uk.ts000066400000000000000000013302731471077622000274070ustar00rootroot00000000000000 AboutDialog About Про програму Version Версія Credits Розробники <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Changelog Журнал змін Info Інформація AntiMicroX AntiMicroX About Development License Ліцензія Program Version %1 Версія програми %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Програму скомпільовано %1 о %2 Built Against SDL %1 Зібрано на SDL %1 Running With SDL %1 Запущено з SDL %1 Using Qt %1 Використано Qt %1 Using Event Handler: %1 Обробник подій: %1 AddEditAutoProfileDialog Auto Profile Dialog Вікно автоматичного профілю Pro&file: Browse Оглянути Window: Вікно: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Оберіть вікно. Натисніть на вікно необхідного додатку, і шлях до нього автоматично заповниться в поле вводу. Detect Window Properties &Class: T&itle: Заголовок: set partial title Встановити частковий заголовок Application: Додаток: Select Обрати De&vices: Пристрої: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Оберіть цей профіль як типовий для вказаного пристрою. Обраний профіль перекриватиме загальні налаштування типового профілю. Set as Default for Controller Встановити типовим для контролера A different profile is already selected as the default for this device. Інший профіль вже встановлено типовим для вказаного пристрою. Current (%1) Поточний (%1) Open Config Відкрити конфігурацію Select Program Обрати програму Programs (*.exe) Please use the main default profile selection. Використовуйте основний типовий профіль. Main Profile Основний профіль Already selected Вже вибрано Chosen Profile Вибраний профіль The selection will be used instead of the all default profile option. Вибране буде використано замість усіх опцій профілю за замовчуванням. Please select a window by using the mouse. Press Escape if you want to cancel. Оберіть мишкою вікно. Аби скасувати вибір натисніть Escape. Capture Application Window Захоплення вікна програми Could not obtain information for the selected window. Не отримано інформації для обраного вікна. Application Capture Failed Захоплення програми зазнало невдачі Profile file path is invalid. Шлях до профілю хибний. No window matching property was specified. Не вказана властивість, яка визначає вікно. Program path is invalid or not executable. Шлях до програми хибний, або вона не має прав на виконання. File is not an .exe file. Файл не є виконуваним файлом з розширенням .exe. No window matching property was selected. AdvanceButtonDialog Advanced Розширені параметри Assignments Призначення Toggle Перемикач Turbo Турбо Set Selector Встановити селектор Press Time Час натиску Insert a pause that occurs in between key presses. Вставте паузу між натисканнями клавіш. Pause Пауза Hold Утримання Mouse Mod Мод. мишки Cycle Цикл Distance Дистанція Release Віджати Blank or KB/M Залишити пустим або вибрати KB/M Delay Затримка Execute Виконати Load Завантажити Set Change Text Entry Текстове значення Insert a new blank slot. Вставити новий пустий слот. Insert Вставити Join З'єднати Split Розділити Delete a slot. Вилучити слот. Delete Вилучити Clear all currently assigned slots. Очистити всі поточні слоти. Clear All Очистити все Placeholder Замінник Specify the duration of an inserted Pause or Hold slot. Встановити тривалість слотів Пауза чи Утримання. Time: Час: 0.01s 0.01с 0m 0хв 0 0 0s &Mouse Speed Mod: &Модифікатор швидкості курсора миші: Set the percentage that mouse speeds will be modified by. Встановіть зміну швидкості миші у відсотковому співвідношенні. % % Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: Дистанція: Auto Reset Cycle After Автоматично скидати цикл опісля seconds секунд Executable: ... ... Arguments: Enabled Увімкнути Mode: Режим: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Звичайний Gradient Наростаючий Pulse Пульсуючий Delay: Затримка: 0.10s 0.10с Rate: Частота: 10.0/s 10.0/с Disabled Вимкнено Select Set 1 One Way Встановити набір 1 одностороннім Select Set 1 Two Way Встановити набір 1 двостороннім Select Set 1 While Held Встановити набір 1 доки натиснуто Select Set 2 One Way Встановити набір 2 одностороннім Select Set 2 Two Way Встановити набір 2 двостороннім Select Set 2 While Held Встановити набір 2 доки натиснуто Select Set 3 One Way Встановити набір 3 одностороннім Select Set 3 Two Way Встановити набір 3 двостороннім Select Set 3 While Held Встановити набір 3 доки натиснуто Select Set 4 One Way Встановити набір 4 одностороннім Select Set 4 Two Way Встановити набір 4 двостороннім Select Set 4 While Held Встановити набір 4 доки натиснуто Select Set 5 One Way Встановити набір 5 одностороннім Select Set 5 Two Way Встановити набір 5 двостороннім Select Set 5 While Held Встановити набір 5 доки натиснуто Select Set 6 One Way Встановити набір 6 одностороннім Select Set 6 Two Way Встановити набір 6 двостороннім Select Set 6 While Held Встановити набір 6 доки натиснуто Select Set 7 One Way Встановити набір 7 одностороннім Select Set 7 Two Way Встановити набір 7 двостороннім Select Set 7 While Held Встановити набір 7 доки натиснуто Select Set 8 One Way Встановити набір 8 одностороннім Select Set 8 Two Way Встановити набір 8 двостороннім Select Set 8 While Held Встановити набір 8 доки натиснуто [NO KEY] [НЕМАЄ КНОПКИ] sec. сек. /sec. /сек. Not checked slots Невідмічені слоти To delete slots, you need to select at least one Для видалення слотів необхідно вибрати принаймні один To insert slots, you need to select at least one Для вставлення слотів необхідно вибрати принаймні один Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Набір %1 Select Set %1 Обрати набір %1 One Way Односторонній Two Way Двосторонній While Held Доки натиснуто Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Призначення стіків/хрестовин Sticks Стіки DPads DPad'и Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) %1 (джойстик %2) Stick 1 Стік 1 Enabled Активний Assign Призначити X Axis: Вісь X: Y Axis: Вісь Y: Stick 2 Стік 2 Number of Physical DPads: %1 Кількість фізичних DPad'ів: %1 Virtual DPad 1 Віртуальний DPad 1 Down: Вниз: Left: Вліво: Right: Вправо: Up: Вверх: Axis %1 Вісь %1 Axis %1 - Вісь %1 - Axis %1 + Вісь %1 + Button %1 Кнопка %1 Move stick 1 along the X axis Рухайте стік 1 по вісі X Move stick 1 along the Y axis Рухайте стік 1 по вісі Y Move stick 2 along the X axis Рухайте стік 2 по вісі X Move stick 2 along the Y axis Рухайте стік 2 по вісі Y Press a button or move an axis Натисніть кнопки чи змістіть вісь AxisEditDialog Axis Вісь Presets: Типовий набір: Mouse (Horizontal) Мишка (Горизонтально) Mouse (Inverted Horizontal) Мишка (Горизонтально інвертовано) Mouse (Vertical) Мишка (Вертикально) Mouse (Inverted Vertical) Мишка (Вертикально інвертовано) Arrows: Up | Down Стрілки: Вверх | Вниз Arrows: Left | Right Стрілки: Вліво | Вправо Keys: W | S Клавіші: W | S Keys: A | D Клавіші: A | D NumPad: KP_8 | KP_2 NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 NumPad: KP_4 | KP_6 None Відсутній Set the value to use as the limit for an axis. Useful for a worn out analog stick. Dead Zone: Сліпа зона: Set the value of the dead zone for an axis. Встановіть значення сліпої зони для вісі. Max Zone: Максимальна зона: [NO KEY] [НЕМАЄ КНОПКИ] Throttle setting that determines the behavior of how to interpret an axis hold or release. Параметри тяги визначають, як програма має реагувати на утримання та натискання вісі. Negative Half Throttle Зворотня напівтяга Negative Throttle Зворотня тяга Normal Звичайний Positive Throttle Пряма тяга Positive Half Throttle Пряма напівтяга Haptic Trigger: Current Value: Поточне значення: Name: Ім'я: Specify the name of an axis. Назначте ім'я для вісі. Mouse Settings Параметри мишки Set Набір Set %1 Набір %1 Left Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog Діалог To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Аби зробити нове призначення, натисніть клавішу на клавіатурі, чи клацніть по кнопці розташованій на вкладках «Клавіатура» чи «Мишка» Placeholder Заповнювач Enables a key press or release to only occur when a controller button is pressed. Дозволяє виконувати дію тільки при натисканні чи відпусканні клавіші. Toggle Перемикач Enables rapid key presses and releases. Turbo controller. Дозволити прискорене натискання клавіш. Турбо контролер. Turbo Турбо Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Last keyboard/mouse button: Slots Слоти Na&me: Ім'я: Specify the name of a button. Назначте ім'я для кнопки. Action: Дія: Specify the action that will be performed in game while this button is being used. Advanced Розширені параметри Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel X X gain offset Y Y Start calibration Close Reset settings Save Зберегти Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Мишка (стандарт) Mouse (Inverted Horizontal) Мишка (Горизонтально інвертовано) Mouse (Inverted Vertical) Мишка (Вертикально інвертовано) Mouse (Inverted Horizontal + Vertical) Мишка (Інвертовано гор.+верт.) Arrows Стрілки Keys: W | A | S | D Клавіші: W | A | S | D NumPad NumPad None Відсутній Standard Стандарт Eight Way Вісім сторін 4 Way Cardinal 4 основні сторони 4 Way Diagonal 4 діагональні сторони Mouse Settings Параметри мишки DPadEditDialog Dialog Діалог Presets: Типовий набір: Mouse (Normal) Мишка (стандарт) Mouse (Inverted Horizontal) Мишка (Горизонтально інвертовано) Mouse (Inverted Vertical) Мишка (Вертикально інвертовано) Mouse (Inverted Horizontal + Vertical) Мишка (Інвертовано гор.+верт.) Arrows Стрілки Keys: W | A | S | D Клавіші: W | A | S | D NumPad NumPad None Відсутній Dpad Mode: Режим DPad: Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. &Name: Standard Стандарт Eight Way Вісім сторін 4 Way Cardinal 4 основні сторони 4 Way Diagonal 4 діагональні сторони DPad Delay: Затримка DPad'а: Time lapsed before a direction change is taken into effect. Час затримки, через який зміна напрямку набуде чинності. s с Specify the name of a dpad. Назначте ім'я для DPad. Mouse Settings Параметри мишки Set Набір Set %1 Набір %1 EditAllDefaultAutoProfileDialog Default Profile Типовий профіль Profile: Профіль: Browse Оглянути Open Config Відкрити конфігурацію Profile file path is invalid. Шлях до профілю некоректний. ExtraProfileSettingsDialog Extra Profile Settings Розширені параметри профілю Key Press Time: Час натиску клавіші: 0.00 ms 0.00 мс Profile Name: Ім'я профілю: s с GameController Game Controller Ігровий контролер GameControllerDPad DPad DPad GameControllerMappingDialog Game Controller Mapping Відображення ігрового контролеру <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A A B B X X Y Y Back Назад Start Старт Guide Guide Left Shoulder Ліве плече Right Shoulder Праве плече Left Stick Click Клік лівого стіку Right Stick Click Клік правого стіку Left Stick X Лівий стік X Left Stick Y Лівий стік Y Right Stick X Правий стік X Right Stick Y Правий стік Y Left Trigger Лівий триґер Right Trigger Правий триґер DPad Up DPad Верх DPad Left DPad Ліво DPad Down DPad Низ DPad Right DPad Право Mapping Відображення SDL 2 Game Controller Mapping String Рядок відображення контролеру від SDL 2 Last Axis Event: Current Axis Detection Dead Zone: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) Відображення ігрового контролеру (%1) (#%2) Discard Controller Mapping? Скинути відображення контролеру? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Назад Guide Guide Start Старт LS Click Клік ЛС RS Click Клік ПС L Shoulder Л плече R Shoulder П плече L Trigger Л триґер R Trigger П триґер GameControllerTrigger Trigger Триґер JoyAccelerometerButton Up Down Left Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis Вісь JoyAxisButton Button Кнопка Negative Зворотній Positive Прямий Unknown Невідомо JoyAxisContextMenu Mouse (Horizontal) Мишка (Горизонтально) Mouse (Inverted Horizontal) Мишка (Горизонтально інвертовано) Mouse (Vertical) Мишка (Вертикально) Mouse (Inverted Vertical) Мишка (Вертикально інвертовано) Arrows: Up | Down Стрілки: Вверх | Вниз Arrows: Left | Right Стрілки: Вліво | Вправо Keys: W | S Клавіші: W | S Keys: A | D Клавіші: A | D NumPad: KP_8 | KP_2 NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 NumPad: KP_4 | KP_6 None Відсутній Mouse Settings Параметри мишки Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button Кнопка [NO KEY] [НЕМАЄ КНОПКИ] [Set %1 1W] [Набір %1 1W] [Set %1 2W] [Набір %1 2W] [Set %1 WH] [Набір %1 WH] JoyButtonContextMenu Toggle Перемкнути Turbo Турбо Clear Очистити Set Select Встановити вибір Disabled Вимкнено Set %1 Набір %1 Set %1 1W Набір %1 1W Set %1 2W Набір %1 2W Set %1 WH Набір %1 WH JoyButtonSlot Mouse Мишка Up Вверх Down Вниз Left Вліво Right Вправо LB ЛК MB СК RB ПК Pause Пауза Hold Утримання Cycle Цикл Distance Дистанція Release Віджати Mouse Mod Мод. мишки Press Time Час натиску Delay Затримка Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] [НЕМАЄ КНОПКИ] JoyControlStick Stick Стік JoyControlStickButton Up Верх Down Низ Left Ліво Right Право Button Кнопка JoyControlStickContextMenu Mouse (Normal) Мишка (Стандарт) Mouse (Inverted Horizontal) Мишка (Горизонтально інвертовано) Mouse (Inverted Vertical) Мишка (Вертикально інвертовано) Mouse (Inverted Horizontal + Vertical) Мишка (Інвертовано гор.+верт.) Arrows Стрілки Keys: W | A | S | D Клавіші: W | A | S | D NumPad NumPad None Відсутній Standard Стандарт Eight Way Вісім сторін 4 Way Cardinal 4 основні сторони 4 Way Diagonal 4 діагональні сторони Mouse Settings Параметри мишки JoyControlStickEditDialog Dialog Діалог X: X: 0 0 Y: Y: Distance: Дистанція: Bearing: Напрям: % Safe Zone: % Безпечна зона: Presets: Типовий набір: Mouse (Normal) Мишка (стандарт) Mouse (Inverted Horizontal) Мишка (Горизонтально інвертовано) Mouse (Inverted Vertical) Мишка (Вертикально інвертовано) Mouse (Inverted Horizontal + Vertical) Мишка (Інвертовано гор.+верт.) Arrows Стрілки Keys: W | A | S | D Клавіші: W | A | S | D NumPad NumPad None Відсутній Stick Mode: Режим стіка: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Standard Стандарт Eight Way Вісім сторін 4 Way Cardinal 4 основні сторони 4 Way Diagonal 4 діагональні сторони Dead Zone: Сліпа зона: Modifier Zone: Dead zone value to use for an analog stick. Max Zone: Максимальна зона: Value when an analog stick is considered moved 100%. Diagonal Range: Діагональний діапазон: The area (in degrees) that each diagonal region occupies. Square Stick: Квадратність стіку: Percentage to modify a square stick coordinates to confine values to a circle % % Stick Delay: Затримка стіка: Time lapsed before a direction change is taken into effect. Час затримки, через який зміна напрямку набуде чинності. s с Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Ім'я: Specify the name of an analog stick. Назначте ім'я для аналогового стіка. Mouse Settings Параметри мишки Set Набір Set %1 Набір %1 JoyControlStickModifierButton Modifier JoyDPad DPad DPad JoyDPadButton Up Верх Down Низ Left Ліво Right Право Button Кнопка JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Кнопка JoySensorContextMenu Mouse Settings Параметри мишки JoySensorEditDialog Dialog Діалог 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Безпечна зона: Presets: Типовий набір: Dead Zone: Сліпа зона: Dead zone value to use for an analog sensor. Max Zone: Максимальна зона: Value when an analog sensor is considered moved 100%. Diagonal Range: Діагональний діапазон: The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. Час затримки, через який зміна напрямку набуде чинності. s с Na&me: Ім'я: Specify the name of an analog sensor. Mouse Settings Параметри мишки Roll (°/s) Pitch (°/s) Yaw (°/s) Set Набір Set %1 Набір %1 JoySensorPreset None Відсутній Mouse (Normal) Mouse (Inverted Horizontal) Мишка (Горизонтально інвертовано) Mouse (Inverted Vertical) Мишка (Вертикально інвертовано) Mouse (Inverted Horizontal + Vertical) Мишка (Інвертовано гор.+верт.) Arrows Стрілки Keys: W | A | S | D Клавіші: W | A | S | D NumPad NumPad JoyTabWidget <New> <Новий> Battery level of controller Remove Вилучити Remove configuration from recent list. Вилучити конфігурацію з переліку частого користування. Load Завантажити Load configuration file. Завантажити файл конфігурації. Save Зберегти Save changes to configuration file. Зберегти зміни до файлу конфігурації. Save As Зберегти як Save changes to a new configuration file. Зберегти зміни в новий файл конфігурації. Sets Набори Copy from Set Копіювати з набору Settings Параметри Set 1 Набір 1 Set 2 Набір 2 Set 3 Набір 3 Set 4 Набір 4 Set 5 Набір 5 Set 6 Набір 6 Set 7 Набір 7 Set 8 Набір 8 Stick/Pad Assign Призначення стіків/DPad Controller Mapping Відображення контролеру Quick Set Швидкий набір Names Імена Toggle button name displaying. Перемкнути показ команд на кнопках. Pref Параметри Change global profile settings. Змінити глобальні параметри профілю. Reset Скинути Revert changes to the configuration. Reload configuration file. Відновити зміни. Перезавантажити файл конфігурації. Open Config Відкрити конфігурацію Config Files (*.amgp *.xml) Save Config Зберегти конфігурацію Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Set Набір Save Profile Changes? Зберегти зміни профілю? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Зміни до нового профілю не збережені. Зберегти їх до поточного профілю? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Зміни до профілю "%1" не збережені. Зберегти їх до поточного профілю? Sticks Стіки Sensors DPads DPad'и No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Жодної кнопки не назначено. Використовуйте «Швидкий набір» для призначення клавіш, або ж вимкніть приховування пустих кнопок. Set %1: %2 Набір %1: %2 Set %1 Набір %1 Copy Set Assignments Скопіювати набір значень Are you sure you want to copy the assignments and device properties from %1? Дійсно бажаєте скопіювати значення і властивості пристрою з %1? Joystick Joystick Джойстик JoystickStatusWindow Properties Властивості Details Деталі Name: Ім'я: %1 %1 Number: Кількість: Axes: Вісь: Buttons: Кнопок: Hats: Міні джойстиків: Sensors: Battery: Unknown Невідомо GUID: GUID: Game Controller: Ігровий контролер: Axes Вісь Buttons Кнопки Hats Міні джойстики Sensors %1 (#%2) Properties Властивості %1 (#%2) Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None Відсутній Axis %1 Вісь %1 Hat %1 Міні джойстик %1 No Ні Yes Так MainSettingsDialog Edit Settings Змінити параметри General Основні Controller Mappings Відображення контролеру Language Мова Auto Profile Авто-профіль Mouse Мишка Advanced Розширені параметри <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>Вкажіть типову теку, яку програма використовуватиме для збереження профілів.</p></body></html> Recent Profile Count: Кількість швидких профілів: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>Кількість профілів, які будуть показані в переліку часто уживаних. Значення 0 трактується програмою, як необмежена кількість профілів для показу.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Приховувати головне вікно кнопкою закриття замість виходу з програми. Close To Tray Закривати до лотку Have Windows start AntiMicroX at system startup. Launch At Windows Startup Запускати разом із Windows Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Виводить часто уживані профілі до всіх контролерів єдиним переліком в меню лотку. Типово використовується підменю. Single Profile List in Tray Один перелік профілів в лотку Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Вказує програмі згортатись до панелі завдань. Зазвичай, програма згортається до системного лотку, якщо є можливість. Minimize to Taskbar Згортати до панелі завдань This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Параметр вказує програмі приховувати всі кнопки, якім не назначено жодного слоту. Використовуйте діалог «Швидкий набір» аби повернути діалог редагування кнопок ігрового контролера. Hide Empty Buttons Приховати пусті кнопки When the program is launched, open the last known profile that was opened during the previous session. Під час запуску програми, відкривається останній відомий профіль, який був відкритий у попередній сесії. Auto Load Last Opened Profile Автоматично завантажувати останній відкритий профіль Only show the system tray icon when the program first launches. Показувати лише піктограму в системному лотку під час першого запуску. Launch in Tray Запускати в лотку Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Прив'язати профілі Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Show low battery notification Show empty battery notification Key Repeat Повтор клавіш Active keys will be repeatedly pressed when this option is enabled. Активні клавіші повторно натискатимуться коли цей параметр активний. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Відсутній Error Warning Info Інформація Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Скинути Class Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Пружинний Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: Затримка: Pro&file Directory: ms мс Rate: Частота: times/s разів/с Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID GUID Mapping String Рядок відображення Disable? Вимкнути? Delete Вилучити Default Типова English English Active Активний Devices: Пристрої: All Всі Device Пристрій Profile Профіль Default? Типовий? Add Додати Edit Змінити AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Обрати типову теку профілю Are you sure you want to delete the profile? Дійсно вилучити профіль? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu Не знайдено жодного джойстика. Будь ласка, під'єднайте джойстик, і натисніть пункт «Оновити джойстики» в головному меню If events are not seen by a game, please click here to run this application as Administrator. Update Button &App Прогр&ама &Options &Параметри He&lp &Quit &Вихід Ctrl+Q Ctrl+Q &Update Joysticks &Оновити джойстики Ctrl+U Ctrl+U &Hide &Згорнути Ctrl+H Ctrl+H &About Пр&о програму Ctrl+A Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page Домашня сторінка (%1) (%1) Open File Відкрити файл Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore &Відновити Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Запустити із правами Адміністратора? Failed to elevate program Не вдалося підняти права програмі Failed to restart this program as the Administrator Не вдалось перезапустити програму із правами Адміністратора MouseAxisSettingsDialog Mouse Settings - Параметри мишки - Set %1 Набір %1 MouseButtonSettingsDialog Mouse Settings - Параметри мишки - Set %1 Набір %1 MouseControlStickSettingsDialog Mouse Settings Параметри мишки Set %1 Набір %1 MouseDPadSettingsDialog Mouse Settings Параметри мишки Set %1 Набір %1 MouseSensorSettingsDialog Mouse Settings Параметри мишки Set %1 Набір %1 MouseSettingsDialog Mouse Settings Параметри мишки Mouse Mode: Режим мишки: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Курсор Spring Пружинний Acceleration: Прискорення: Enhanced Precision Покращена точність Linear Лінійне Quadratic Квадратичне Cubic Кубічне Quadratic Extreme Екстремально квадратичне Power Function По степеневій функції Easing Quadratic Просте квадратичне Easing Cubic Просте кубічне Mouse Speed Settings Параметри швидкості мишки Enable to change the horizontal and vertical speed boxes at the same time. Змінювати значення гоизонтальної та вертикальної швидкості разом. Change Together Змінювати разом Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: E&xtra Duration: 1 = 20 pps 1 = 20 pps Wheel Hori. Speed: Коліщатко горизонт.: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Встановіть швидкість для горизонтальної прокрутки коліщатка миші відносно від числа симуляції кроків за секунду. 1 = 1 notch(es)/s 1 = 1 крок(ів)/с Wheel Vert. Speed: Коліщатко вертикаль.: Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Встановіть швидкість для вертикальної прокрутки коліщатка миші відносно від числа симуляції кроків за секунду. For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: % % Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Sensitivit&y: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. s с Highest value to accelerate mouse movement by x x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Spring Settings Параметри пружини Spring Width: Ширина пружини: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Висота пружини: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Відносний Mouse Status Стан мишки X: X: 0 (0 pps) 0 (0 pps) Y: Y: %n notch(es)/s %n крок/с %n кроки/с %n кроків/с QKeyDisplayDialog Key Checker Перевірка клавіш <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Обробник подій: Native Key Value: Нативне значення клавіші: 0x00000000 0x00000000 Qt Key Value: Значення клавіші Qt: antimicro Key Value: QObject Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 # джойстиків знайдено: %1 List Joysticks: Перелік джойстиків: --------------- --------------- Joystick %1: Джойстик %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Super Super Menu Меню Mute Mute Vol+ Vol+ Vol- Vol- Play/Pause Play/Pause Play Play Pause Pause Prev Prev Next Next Mail Пошта Home Home Media Media Search Пошук Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Профіль %1 не є XML файлом. Profile location %1 does not exist. Профіль %1 не існує. Controller identifier is not a valid value. Контролер має хибне значення ідентифікатора. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. Не вказаний набір значень. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Версія xinput має бути вище 2.0. Зміна швидкості миші не використовується. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set Швидкий набір <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>Натисніть кнопку, чи змістіть вісь по %1 (<span style=" font-weight:600;">%2</span>).<br/>З'явиться діалогове вікно<br/>в якому зможете зробити переназначення.</p></body></html> Quick Set %1 Швидкий набір %1 SetAxisThrottleDialog Throttle Change Зміна тяги The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? Параметри тяги були змінені для вісі %1. Застосувати ці зміни до всіх наборів? SetJoystick Set %1: %2 Набір %1: %2 Set %1 Набір %1 SetNamesDialog Set Name Settings Параметри наборів Set 1 Набір 1 Set 2 Набір 2 Set 3 Набір 3 Set 4 Набір 4 Set 5 Набір 5 Set 6 Набір 6 Set 7 Набір 7 Set 8 Набір 8 Name Ім'я SimpleKeyGrabberButton Mouse Мишка SpringModeRegionPreview Spring Mode Preview Перегляд пружинного режиму UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Не можливо знайти прийнятний файл пристрою uinput. Перевірте, чи завантажений модуль uinput. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Неможливо відкрити uinput файл пристрою Перевірте, чи маєте ви права на запис до пристрою Using uinput device file %1 UInputHelper a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z Esc Esc F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace BackSpace Tab Tab [ [ ] ] \ \ CapsLock CapsLock ; ; ' ' Enter Enter Shift_L Shift_Л , , . . / / Ctrl_L Ctrl_Л Super_L Super_Л Alt_L Alt_Л Space Пробіл Alt_R Alt_П Menu Меню Ctrl_R Ctrl_П Shift_R Shift_П Up Вверх Left Вліво Down Вниз Right Вправо PrtSc PrtSc Ins Ins Del Del Home Home End End PgUp PgUp PgDn PgDn NumLock NumLock * * + + KP_Enter KP_Enter KP_1 KP_1 KP_2 KP_2 KP_3 KP_3 KP_4 KP_4 KP_5 KP_5 KP_6 KP_6 KP_7 KP_7 KP_8 KP_8 KP_9 KP_9 KP_0 KP_0 SCLK SCLK Pause Pause Super_R Super_П Mute Mute VolDn VolDn VolUp VolUp Play Play Stop Stop Prev Prev Next Next [NO KEY] [НЕМАЄ КНОПКИ] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VDPad VirtualKeyPushButton Space Пробіл Tab Tab Shift (L) Shift (Л) Shift (R) Shift (П) Ctrl (L) Ctrl (Л) Ctrl (R) Ctrl (П) Alt (L) Alt (Л) Alt (R) Alt (П) Alt Gr ` ` ~ ~ - - = = [ [ ] ] \ \ Caps Caps ; ; ' ' , , . . / / ESC ESC PRTSC PRTSC SCLK SCLK INS INS PGUP PGUP DEL DEL PGDN PGDN 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK NUM LK * * + + Enter Enter Del Del < < : : Super (L) Super (Л) Menu Меню Up Вверх Down Вниз Left Вліво Right Вправо VirtualKeyboardMouseWidget Keyboard Клавіатура Mouse Мишка Left Mouse Вліво Up Mouse Вверх Left Button Mouse Ліва кнопка Middle Button Mouse Середня кнопка Right Button Mouse Права кнопка Wheel Up Mouse Коліщатко вверх Wheel Left Mouse Коліщатко вліво Wheel Right Mouse Коліщатко вправо Wheel Down Mouse Коліщатко вниз Down Mouse Вниз Right Mouse Вправо Button 4 Mouse Кнопка 4 Mouse 8 Mouse Мишка 8 Button 5 Mouse Кнопка 5 Mouse 9 Mouse Мишка 9 Mouse Settings Параметри мишки NONE Відсутній [NO KEY] [НЕМАЄ КНОПКИ] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media Media Media Next Media Play Media Previous Media Stop Search Пошук Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID ХИБНИЙ WinAppProfileTimerDialog Capture Application Захопити програму After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Після натискання «Захопити програму», зробіть активним вікно програм, яку ви хочете прив'язати до поточного профілю. Активне вікно буде захоплено через вказаний проміжок часу. Timer: Таймер: Seconds Секунд Cancel Скасувати WinExtras [NO KEY] [НЕМАЄ КНОПКИ] AntiMicro Profile X11Extras ESC ESC Tab Tab Space Пробіл DEL DEL Return Return KP_Enter KP_Enter Backspace Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. Розширення xinput не знайдено. Зміна швидкості миші не використовується. xinput version must be at least 2.0. No mouse acceleration changes will occur. Версія xinput має бути вище 2.0. Зміна швидкості миші не використовується. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Не знайдено PtrFeedbackClass для віртуального вказівника. Зміна швидкості миші не використовується для пристрою із id=%1 Changing mouse acceleration for device with id=%1 Зміна прискорення мишки для пристрою із id=%1 XMLConfigReader Could not write updated profile XML to file %1. Неможливо записати оновлений профіль до файлу %1. XMLConfigWriter Could not write to profile at %1. Неможливо записати профіль як %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Запустити програму згорнутою у системний лоток. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_vi.ts000066400000000000000000013057171471077622000274130ustar00rootroot00000000000000 AboutDialog About về Version Phiên bản Info Thông tin Changelog Lịch sử thay đổi Credits AntiMicroX AntiMicroX <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> About Development "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Copyright: 2013 - 2022 {2013 ?} License Program Version %1 Compiled from packaging: %1 Program Compiled on %1 at %2 Built Against SDL %1 Running With SDL %1 Using Qt %1 Using Event Handler: %1 AddEditAutoProfileDialog Auto Profile Dialog Pro&file: Browse Window: Select Window. Click on the appropriate application window and the application file path will be populated in the form. Detect Window Properties &Class: T&itle: set partial title Application: Select De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Set as Default for Controller A different profile is already selected as the default for this device. Current (%1) Open Config Select Program Programs (*.exe) Please use the main default profile selection. Main Profile Already selected Chosen Profile The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. Capture Application Window Could not obtain information for the selected window. Application Capture Failed Profile file path is invalid. No window matching property was specified. Program path is invalid or not executable. File is not an .exe file. No window matching property was selected. AdvanceButtonDialog Advanced Assignments Toggle Turbo Set Selector Blank or KB/M Hold Pause Cycle Distance Insert Delete Clear All Time: 0.01s 0s Insert a pause that occurs in between key presses. Release Insert a new blank slot. Delete a slot. Clear all currently assigned slots. Specify the duration of an inserted Pause or Hold slot. 0m &Mouse Speed Mod: Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: % Mouse Mod Press Time Delay Execute Load Set Change Text Entry Join Split Placeholder 0 Set the percentage that mouse speeds will be modified by. Auto Reset Cycle After seconds Executable: ... Arguments: Enabled Mode: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Delay: 0.10s Rate: 10.0/s Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held [NO KEY] sec. /sec. Not checked slots To delete slots, you need to select at least one To insert slots, you need to select at least one Unknown current slot Click on chosen slots before joining them Not enough slots It's impossible to join slots. Add at least one other slot. Not selected slots It's impossible to join slots. Select at least two slots before joining them Only keyboard slots It's only possible to join simple and mix keyboard slots It's impossible to split slots. Add at least one other slot. Not selected slot Select your slot before splitting. Too many mix slots Select one mix slot. Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist There is no such file locally, that could be executed. Check the file on your system Set %1 Select Set %1 One Way Two Way While Held Choose Executable Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. Chose a profile to load when this slot is activated. Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. Specify the time that keys past this slot should be held down. Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. Change to selected set once slot is activated. Full string will be typed when a slot is activated. Execute program when slot is activated. Choose Profile Config Files (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment Sticks DPads Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) Stick 1 Enabled Assign X Axis: Y Axis: Stick 2 Number of Physical DPads: %1 Virtual DPad 1 Up: Down: Left: Right: Axis %1 Axis %1 - Axis %1 + Button %1 Move stick 1 along the X axis Move stick 1 along the Y axis Move stick 2 along the X axis Move stick 2 along the Y axis Press a button or move an axis AxisEditDialog Axis Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. Negative Half Throttle Positive Half Throttle Haptic Trigger: Name: Specify the name of an axis. Mouse Settings Set the value of the dead zone for an axis. Presets: Dead Zone: Max Zone: [NO KEY] Throttle setting that determines the behavior of how to interpret an axis hold or release. Negative Throttle Normal Positive Throttle Current Value: Set Set %1 Left Mouse Button Right Mouse Button Click Rigid Rigid Gradient Vibration ButtonEditDialog Dialog To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab Placeholder Toggle Enables a key press or release to only occur when a controller button is pressed. Enables rapid key presses and releases. Turbo controller. Turbo Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Attach the numeric keypad Last keyboard/mouse button: Slots Na&me: Specify the name of a button. Action: Specify the action that will be performed in game while this button is being used. Advanced Choose your keyboard key No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set Index %1 Calibration Form Input to calibrate: Steps Z TextLabel TextLabel X X gain offset Y Y Start calibration Close Reset settings Save Calibration Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path Full Path File Name DPadContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings DPadEditDialog Dialog Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: &Name: 4 Way Cardinal 4 Way Diagonal DPad Delay: Time lapsed before a direction change is taken into effect. s Specify the name of a dpad. Mouse Settings Standard Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Eight Way Set Set %1 EditAllDefaultAutoProfileDialog Default Profile Profile: Browse Open Config Profile file path is invalid. ExtraProfileSettingsDialog Extra Profile Settings Key Press Time: 0.00 ms Profile Name: s GameController Game Controller GameControllerDPad DPad GameControllerMappingDialog Game Controller Mapping <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping SDL 2 Game Controller Mapping String Last Axis Event: Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Game Controller Mapping (%1) (#%2) Discard Controller Mapping? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. GameControllerSet Back Guide Start LS Click RS Click L Shoulder R Shoulder L Trigger R Trigger GameControllerTrigger Trigger JoyAccelerometerButton Up Up Down Down Left Left Right Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Negative Positive Unknown Button JoyAxisContextMenu Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Mouse Settings Left Mouse Button Right Mouse Button JoyButton Processing turbo for #%1 - %2 Finishing turbo for button #%1 - %2 Distance change for button #%1 - %2 Button [NO KEY] [Set %1 1W] [Set %1 2W] [Set %1 WH] JoyButtonContextMenu Toggle Turbo Clear Set Select Disabled Set %1 Set %1 1W Set %1 2W Set %1 WH JoyButtonSlot Mouse Up Down Left Right LB MB RB Pause Hold Cycle Distance Release Mouse Mod Press Time Delay Load %1 Set Change %1 [Text] %1 [Exec] %1 [NO KEY] JoyControlStick Stick JoyControlStickButton Up Down Left Right Button JoyControlStickContextMenu Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Standard Eight Way 4 Way Cardinal 4 Way Diagonal Mouse Settings JoyControlStickEditDialog Dialog X: 0 Y: Distance: Presets: Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 4 Way Cardinal 4 Way Diagonal Modifier Zone: Dead zone value to use for an analog stick. Value when an analog stick is considered moved 100%. The area (in degrees) that each diagonal region occupies. Square Stick: Percentage to modify a square stick coordinates to confine values to a circle % Stick Delay: Time lapsed before a direction change is taken into effect. s Modifier: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: Specify the name of an analog stick. Mouse Settings Standard Bearing: % Safe Zone: Eight Way Dead Zone: Max Zone: Diagonal Range: Set Set %1 JoyControlStickModifierButton Modifier JoyDPad DPad JoyDPadButton Up Down Left Right Button JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button Button JoySensorContextMenu Mouse Settings Mouse Settings JoySensorEditDialog Dialog Dialog 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: % Safe Zone: Presets: Presets: Dead Zone: Dead Zone: Dead zone value to use for an analog sensor. Max Zone: Max Zone: Value when an analog sensor is considered moved 100%. Diagonal Range: Diagonal Range: The area (in degrees) that each diagonal region occupies. The area (in degrees) that each diagonal region occupies. Sensor Delay: Time lapsed before a direction change is taken into effect. Time lapsed before a direction change is taken into effect. s s Na&me: Na&me: Specify the name of an analog sensor. Mouse Settings Mouse Settings Roll (°/s) Pitch (°/s) Yaw (°/s) Set Set Set %1 Set %1 JoySensorPreset None None Mouse (Normal) Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Arrows Keys: W | A | S | D Keys: W | A | S | D NumPad NumPad JoyTabWidget <New> Battery level of controller Remove Remove configuration from recent list. Load Load configuration file. Save Save changes to configuration file. Save As Save changes to a new configuration file. Sets Copy from Set Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Stick/Pad Assign Controller Mapping Quick Set Names Toggle button name displaying. Pref Change global profile settings. Reset Revert changes to the configuration. Reload configuration file. Open Config Config Files (*.amgp *.xml) Config File (*.%1.amgp) Do you really want to reset buttons settings for joystick? Save Profile Changes? Changes to the new profile have not been saved. Would you like to save or discard the current profile? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? Sticks Sensors DPads No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. Set %1: %2 Set %1 Copy Set Assignments Are you sure you want to copy the assignments and device properties from %1? Save Config Set Joystick Joystick JoystickStatusWindow Properties Details Name: %1 Number: Axes: Buttons: Hats: Sensors: Battery: Unknown GUID: Game Controller: Axes Buttons Hats Sensors %1 (#%2) Properties Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None None Axis %1 Hat %1 No Yes MainSettingsDialog Edit Settings General Controller Mappings Language Auto Profile Mouse Advanced <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Specifies how much time should elapse before key repeating begins. Specifies how many times key presses will be performed per seconds. <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> Português do Brasil Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski History Si&ze: Weight Modi&fier: Log File: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: None Error Warning Info Verbose Debug Note: To see the change of log level in console output (not in log file), application restart is required Reset Class Pro&file Directory: Show low battery notification Show empty battery notification Title Program Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision Smoothing Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring Screen: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. Accel Numerator: 0 Accel Denominator: Accel Threshold: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Delay: ms Rate: times/s Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. GUID Mapping String Disable? Delete Default English Active Devices: All Device Profile Default? Add Edit AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. Select Default Profile Directory Are you sure you want to delete the profile? Save Log File As Log Files (*.log) Do you really want to reset setting? Would you like to reset mappings too? MainWindow AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu If events are not seen by a game, please click here to run this application as Administrator. Update Button &App &Options He&lp &Quit Ctrl+Q &Update Joysticks Ctrl+U &Hide Ctrl+H &About Ctrl+A About &Qt Ctrl+T &Properties Ctrl+P &Key Checker Ctrl+K &GitHub Page Ctrl+G S&ettings Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration Ctrl+C Home Page (%1) Open File Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery Battery level is less than %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore Calibration couldn't be opened You must connect at least one controller to open the window Run as Administrator? Failed to elevate program Failed to restart this program as the Administrator MouseAxisSettingsDialog Mouse Settings - Set %1 MouseButtonSettingsDialog Mouse Settings - Set %1 MouseControlStickSettingsDialog Mouse Settings Set %1 MouseDPadSettingsDialog Mouse Settings Set %1 MouseSensorSettingsDialog Mouse Settings Mouse Settings Set %1 Set %1 MouseSettingsDialog Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring Acceleration: Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Mouse Speed Settings Enable to change the horizontal and vertical speed boxes at the same time. Change Together Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration &Multiplier: Mi&n Threshold: 1 = 20 pps Wheel Hori. Speed: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. Sensitivit&y: For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. Easing Duration: s Highest value to accelerate mouse movement by x Start %: Acceleration begins at this percentage of the base multiplier Minimum amount of axis travel required for acceleration to begin Max Threshold: Maximum axis travel before acceleration has reached the multiplier value E&xtra Duration: Curve: Ease Out Sine Ease Out Quad Ease Out Cubic Release Radius: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Mouse Status X: 0 (0 pps) Y: 1 = 1 notch(es)/s Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Hori&zontal Speed: &Vertical Speed: Wheel Vert. Speed: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. % Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. Spring Settings Spring Width: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. Spring Height: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. %n notch(es)/s QKeyDisplayDialog Key Checker <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: Native Key Value: 0x00000000 Qt Key Value: antimicro Key Value: QObject Super Menu Mute Vol+ Vol- Play/Pause Play Pause Prev Next Mail Home Media Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program # of joysticks found: %1 List Joysticks: --------------- Joystick %1: Attempting to use fallback option %1 for event generation. Failed to open event generator. Exiting. Using %1 as the event generator. Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. Profile location %1 does not exist. Controller identifier is not a valid value. An invalid set number '%1' was specified. Controller identifier '%s'' is not a valid value. No set number was specified. An invalid event generator was specified. No event generator string was specified. Unknown log level: No log file specified. xinput version must be at least 2.0. No mouse acceleration changes will occur. Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Quick Set %1 SetAxisThrottleDialog Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? SetJoystick Set %1: %2 Set %1 SetNamesDialog Set Name Settings Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name SimpleKeyGrabberButton Mouse SpringModeRegionPreview Spring Mode Preview UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device Using uinput device file %1 UInputHelper a b c d e f g h i j k l m n o p q r s t u v w x y z Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 ` 1 2 3 4 5 6 7 8 9 0 - = BackSpace Tab [ ] \ CapsLock ; ' Enter Shift_L , . / Ctrl_L Super_L Alt_L Space Alt_R Menu Ctrl_R Shift_R Up Left Down Right PrtSc Ins Del Home End PgUp PgDn NumLock * + KP_Enter KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9 KP_0 SCLK Pause Super_R Mute VolDn VolUp Play Stop Prev Next [NO KEY] UnixWindowInfoDialog Captured Window Properties Information About Window Class: TextLabel Title: Path: Match By Properties Class Title Path VDPad VDPad VirtualKeyPushButton Space Tab Shift (L) Shift (R) Ctrl (L) Ctrl (R) Alt (L) Alt (R) Alt Gr ` ~ - = [ ] \ Caps ; ' , . / ESC PRTSC SCLK INS PGUP DEL PGDN 1 2 3 4 5 6 7 8 9 0 NUM LK * + Enter Del < : Super (L) Menu Up Down Left Right VirtualKeyboardMouseWidget Keyboard Mouse Mouse Settings Left Mouse Up Mouse Left Button Mouse Middle Button Mouse Right Button Mouse Wheel Up Mouse Wheel Left Mouse Wheel Right Mouse Wheel Down Mouse Down Mouse Right Mouse Button 4 Mouse Mouse 8 Mouse Button 5 Mouse Mouse 9 Mouse NONE [NO KEY] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others Applications Browser Back Browser Favorites Browser Forward Browser Home Browser Refresh Browser Search Browser Stop Calc Email F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 Media Media Next Media Play Media Previous Media Stop Search Volume Down Volume Mute Volume Up VirtualMousePushButton INVALID WinAppProfileTimerDialog Capture Application After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. Timer: Seconds Cancel WinExtras [NO KEY] AntiMicro Profile X11Extras ESC Tab Space DEL Return KP_Enter Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. xinput version must be at least 2.0. No mouse acceleration changes will occur. PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 Changing mouse acceleration for device with id=%1 XMLConfigReader Could not write updated profile XML to file %1. XMLConfigWriter Could not write to profile at %1. antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/antimicrox/translations/antimicrox_zh_CN.ts000066400000000000000000013143721471077622000277730ustar00rootroot00000000000000 AboutDialog About 关于 AntiMicroX AntiMicroX Version 版本 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Cantarell'; font-size:10pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Next maintained by the AntiMicro group at https://github.com/AntiMicro.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Then by juliagoda at https://github.com/juliagoda.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Now maintained at https://github.com/AntiMicroX/antimicrox.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt; font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">https://github.com/AntiMicroX/antimicrox/graphs/contributors</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-weight:600;">Translators:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-weight:600;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">VaGNaroK &lt;vagnarokalkimist@gmail.com&gt; - Brazilian Portuguese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">zzpxyx - Chinese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Belleguic Terence &lt;hizo@free.fr&gt; - French</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:9pt;">Leonard Koenig &lt;leonard.r.koenig@googlemail.com&gt; - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">phob - German</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">tou omiya - Japanese</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Dmitriy Koshel &lt;form.eater@gmail.com&gt; - Russian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Jay Alexander Fleming &lt;tito.nehru.naser@gmail.com&gt; - Serbian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">burunduk - Ukrainian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">Flavio HR &lt;flavio.hrx@gmail.com&gt; - Spanish</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">WAZAAAAA - wazaaaaa00&lt;@&gt;gmail&lt;.&gt;com - Italian</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:9pt;">juliagoda &lt;juliagoda.pl@protonmail.com&gt; - Polish</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to conticue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 版权:2013 - 2022 Info 信息 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> Changelog 更新日志 Credits 致谢 About Development 关于开发 License 许可 Program Version %1 程序版本 %1 Compiled from packaging: %1 Program Compiled on %1 at %2 编译时间 %1 %2 Built Against SDL %1 使用 SDL %1 构建 Running With SDL %1 使用 SDL %1 运行 Using Qt %1 使用 Qt %1 Using Event Handler: %1 使用事件处理程序:%1 AddEditAutoProfileDialog Auto Profile Dialog 自动配置文件对话框 Pro&file: Browse 浏览 Window: 窗口: Select Window. Click on the appropriate application window and the application file path will be populated in the form. 选择窗口。 单击应用程序的窗口,程序文件路径将被自动填入表格。 Detect Window Properties 检测窗口属性 &Class: T&itle: set partial title Application: 应用程序: Select 选择 De&vices: Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. 将这个配置文件设定为上述设备的默认配置文件。 这个配置文件将取代全局默认配置文件选项。 Set as Default for Controller 设为上述设备的默认配置文件 A different profile is already selected as the default for this device. 这个设备已被指定了另一个不同的默认配置文件。 Current (%1) 当前 (%1) Open Config 打开配置文件 Select Program 选择程序 Programs (*.exe) 程序 (*.exe) Please use the main default profile selection. 请使用全局默认配置文件选项。 Main Profile 主配置文件 Already selected 已经选择的 Chosen Profile 选择配置 The selection will be used instead of the all default profile option. Please select a window by using the mouse. Press Escape if you want to cancel. 请使用鼠标选择窗口。按 Esc 键取消。 Capture Application Window 捕捉应用程序窗口 Could not obtain information for the selected window. 无法获得所选窗口的信息。 Application Capture Failed 应用程序捕捉失败 Profile file path is invalid. 配置文件路径无效。 No window matching property was specified. 未指定窗口匹配属性。 Program path is invalid or not executable. 程序路径无效或非可执行文件。 File is not an .exe file. 文件不是 .exe 文件。 No window matching property was selected. 未选择窗口匹配属性。 AdvanceButtonDialog Advanced 高级选项 Assignments 分配 Toggle 开关 Turbo 连发 Set Selector 设置选择器 Blank or KB/M 空白或键鼠 Hold 按下 Pause 暂停 Cycle 周期 Distance 距离 Insert 插入 Delete 删除 Clear All 清除所有 Time: 时间: 0.01s 0.01秒 0s 0秒 Insert a pause that occurs in between key presses. 在按键间插入暂停。 Release 释放 Insert a new blank slot. 插入新动作。 Delete a slot. 删除所选动作。 Clear all currently assigned slots. 清除所有动作。 Specify the duration of an inserted Pause or Hold slot. 为“暂停”或“按下”动作指定所需时长。 0m 0分 &Mouse Speed Mod: 鼠标速度更改 (&M): Specify the range past an axis dead zone in which a sequence of actions will execute. 为“距离”动作指定所需的超过不灵敏区的距离。 Distance: 距离: % % Mouse Mod 鼠标变速 Press Time 按下时间 Delay 延迟 Execute 运行 Load 载入 Set Change 设置改变 Text Entry 文本键入 Join 混合 Split 拆分 Placeholder 占位符 0 0 Set the percentage that mouse speeds will be modified by. 设置鼠标移动速度百分比。 Auto Reset Cycle After 在此时间之后取消未完成的“周期”动作 seconds Executable: 可执行文件: ... ... Arguments: 参数: Enabled 启用 Mode: 模式: <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> <html><head/><body><p>正常:以所选频率重复按下并释放按键。</p><p>梯度:根据轴移动幅度调整按钮被按下和释放的延迟。频率保持不变。</p><p>脉冲:调整每秒按钮被按下和释放的次数。按钮延迟保持不变。</p></body></html> Normal 正常 Gradient 梯度 Pulse 脉冲 Delay: 延迟: 0.10s 0.10秒 Rate: 频率: 10.0/s 10.0/秒 Disabled 禁用 Select Set 1 One Way 单向选择设置1 Select Set 1 Two Way 双向选择设置1 Select Set 1 While Held 按下时选择设置1 Select Set 2 One Way 单向选择设置2 Select Set 2 Two Way 双向选择设置2 Select Set 2 While Held 按下时选择设置2 Select Set 3 One Way 单向选择设置3 Select Set 3 Two Way 双向选择设置3 Select Set 3 While Held 按下时选择设置3 Select Set 4 One Way 单向选择设置4 Select Set 4 Two Way 双向选择设置4 Select Set 4 While Held 按下时选择设置4 Select Set 5 One Way 单向选择设置5 Select Set 5 Two Way 双向选择设置5 Select Set 5 While Held 按下时选择设置5 Select Set 6 One Way 单向选择设置6 Select Set 6 Two Way 双向选择设置6 Select Set 6 While Held 按下时选择设置6 Select Set 7 One Way 单向选择设置7 Select Set 7 Two Way 双向选择设置7 Select Set 7 While Held 按下时选择设置7 Select Set 8 One Way 单向选择设置8 Select Set 8 Two Way 双向选择设置8 Select Set 8 While Held 按下时选择设置8 [NO KEY] [无按键] sec. 秒。 /sec. /秒。 Not checked slots 未选择插槽 To delete slots, you need to select at least one 至少要选择一个插槽才能删除 To insert slots, you need to select at least one 至少要选择一个插槽才能插入 Unknown current slot 当前插槽未知 Click on chosen slots before joining them 加入选中插槽前点击它 Not enough slots 没有足够的插槽 It's impossible to join slots. Add at least one other slot. Not selected slots 没有选择插槽 It's impossible to join slots. Select at least two slots before joining them 无法混合插槽,至少需要选择两个插槽 Only keyboard slots It's only possible to join simple and mix keyboard slots 只能混合普通键盘插槽和混合键盘插槽 It's impossible to split slots. Add at least one other slot. 不可分割插槽,请至少添加一个其他插槽。 Not selected slot 未选择插槽 Select your slot before splitting. 在拆分插槽前请先选择一个插槽。 Too many mix slots 混合插槽过多 Select one mix slot. 选择一个混合插槽。 Only mix slots It's only possible to split mix slot. Empty execution path Line for execution file path is empty. Fill the first line before you are going to add a slot. File doesn't exist 文件不存在 There is no such file locally, that could be executed. Check the file on your system 没有本地文件可以运行,请检查文件系统 Set %1 设置%1 Select Set %1 选择设置%1 One Way 单向 Two Way 双向 While Held 按下时 Choose Executable 选择可执行文件 Slots past a Cycle action will be executed on the next button press. Multiple cycles can be added in order to create partitions in a sequence. “周期”动作之后的动作将在下一次按下相同按钮的时候被执行。可以添加多个“周期”动作来创建一个按键序列中不同的子序列。 Delays the time that the next slot is activated by the time specified. Slots activated before the delay will remain active after the delay time has passed. 根据指定时长延迟下个动作开始执行的时间。延迟之前处于活动状态的动作将在延迟结束后保持活动状态。 Distance action specifies that the slots afterwards will only be executed when an axis is moved a certain range past the designated dead zone. “距离”动作之后的动作只有在轴移出不灵敏区并超过指定距离之后才会被执行。 Insert a hold action. Slots after the action will only be executed if the button is held past the interval specified. 插入一个“按下”动作。“按下”动作之后的动作只有在按钮被按下超过指定的时长之后才会被执行。 Chose a profile to load when this slot is activated. 当该动作被执行时,载入所选配置文件。 Mouse mod action will modify all mouse speed settings by a specified percentage while the action is being processed. This can be useful for slowing down the mouse while sniping. “鼠标变速”动作被处理时,将根据指定的百分比改变所有鼠标速度。这可以用在狙击时减缓鼠标速度。 Specify the time that keys past this slot should be held down. 按钮被按下超过指定的时长将保持被按下的状态。 Insert a release action. Slots after the action will only be executed after a button release if the button was held past the interval specified. 插入一个“释放”动作。“释放”动作之后的动作只有在按钮被按下超过指定时长并被释放之后才会被执行。 Change to selected set once slot is activated. 该动作被执行时,切换到所选的设置。 Full string will be typed when a slot is activated. 当该动作被执行时,整个字符串将被键入。 Execute program when slot is activated. 当该动作被执行时,运行一个程序。 Choose Profile 选择配置文件 Config Files (*.amgp *.xml) 配置文件 (*.amgp *.xml) AdvanceStickAssignmentDialog Stick/Pad Assignment 摇杆/十字键分配 Sticks 摇杆 DPads 十字键 Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. %1 (Joystick %2) %1(手柄%2) Stick 1 手柄1 Enabled 启用 Assign 分配 X Axis: X轴: Y Axis: Y轴: Stick 2 手柄2 Number of Physical DPads: %1 物理十字键数:%1 Virtual DPad 1 虚拟十字键1 Up: 上: Down: 下: Left: 左: Right: 右: Axis %1 轴%1 Axis %1 - 轴%1 - Axis %1 + 轴%1 + Button %1 按钮%1 Move stick 1 along the X axis 沿X轴移动摇杆1 Move stick 1 along the Y axis 沿Y轴移动摇杆1 Move stick 2 along the X axis 沿X轴移动摇杆2 Move stick 2 along the Y axis 沿Y轴移动摇杆2 Press a button or move an axis 按任意键或移动任意轴 AxisEditDialog Axis Mouse (Horizontal) 鼠标(水平) Mouse (Inverted Horizontal) 鼠标(水平翻转) Mouse (Vertical) 鼠标(垂直) Mouse (Inverted Vertical) 鼠标(垂直翻转) Arrows: Up | Down 方向键:上|下 Arrows: Left | Right 方向键:左|右 Keys: W | S 按键:W | S Keys: A | D 按键:A | D NumPad: KP_8 | KP_2 数字键盘:8 | 2 NumPad: KP_4 | KP_6 数字键盘:4 | 6 None Set the value to use as the limit for an axis. Useful for a worn out analog stick. 设置轴的最大值。 对老旧磨损的模拟摇杆尤其有帮助。 Negative Half Throttle 负半阀 Positive Half Throttle 正半阀 Haptic Trigger: Name: 名称: Specify the name of an axis. 指定轴的名称。 Mouse Settings 鼠标设置 Set the value of the dead zone for an axis. 设置轴的不灵敏区。 Presets: 预设: Dead Zone: 不灵敏区: Max Zone: 最大区: [NO KEY] [无按键] Throttle setting that determines the behavior of how to interpret an axis hold or release. 阀设置决定如何判断一个轴的按下和释放。 Negative Throttle 负阀 Normal 正常 Positive Throttle 正阀 Current Value: 当前值: Set 设置 Set %1 设置%1 Left Mouse Button 鼠标左键 Right Mouse Button 鼠标右键 Click 点击 Rigid Rigid Gradient Vibration 震动 ButtonEditDialog Dialog 对话框 To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab 若想分配按键,请按键盘上任意键或在键盘、鼠标页上点击按钮 Placeholder 占位符 Toggle 开关 Enables a key press or release to only occur when a controller button is pressed. 当游戏控制器按钮被按下时,按下或释放某个按键,并一直保持此状态。 Enables rapid key presses and releases. Turbo controller. 快速按下和释放某个键。 连发游戏控制器。 Turbo 连发 Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Last keyboard/mouse button: Slots 动作 Na&me: 名称 (&m): Specify the name of a button. 指定按钮的名称。 Action: 动作: Specify the action that will be performed in game while this button is being used. 指定游戏中这个按钮被按下时的动作。 Advanced 高级选项 Choose your keyboard key 选择要映射按键 No button Last button To change settings for last button, it must be at least one assignment from keyboard to gamepad To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad No choice Before you open window with advanced settings, you have to choice a key 请先绑定一个按键再进入高级选项 To open advanced dialog, it's needed to map at least one button from keyboard to gamepad Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad As last gamepad button has been set 最后一个已设置的按键为 Index %1 Calibration Form Input to calibrate: Steps Z TextLabel 文本标签 X X键 gain offset Y Y键 Start calibration Close Reset settings 重置设置 Save 保存 Calibration 校准 Gyroscope Accelerometer Selected device doesn't have any inputs to calibrate. Calibration was not saved for the preset. Do you really want to continue? Do you really want to reset calibration of current device? Accelerometer calibration sets the neutral controller orientation. Gyroscope calibration corrects the sensor offset. This prevents cursor movement while the controller is at rest. Calibration completed. Offset calibration completed. Click "Continue calibration" to continue with gain calibration. Hold the controller in the desired neutral position and press continue. Calibrating accelerometer Collecting accelerometer data... Please hold the controller still. This can take up to %1 seconds. Place the controller at rest, e.g. put it on the desk, and press continue. Calibrating gyroscope Collecting gyroscope data... This can take up to %1 seconds. Now move the stick several times to the maximum in different direction and back to center. This can take up to %1 seconds. Calibrating stick Continue calibration Now move the stick in full circles for several times. This can take up to %1 seconds. Calibration was saved for the preset. Do you really want to reset settings? CapturedWindowInfoDialog Captured Window Properties 捕获的窗口属性 Information About Window 窗口信息 Class: 类: TextLabel 文本标签 Title: 标题: Path: 路径: Match By Properties 根据属性匹配 Class Title 标题 Path 路径 Full Path 全路径 File Name 文件名 DPadContextMenu Mouse (Normal) 鼠标(正常) Mouse (Inverted Horizontal) 鼠标(水平翻转) Mouse (Inverted Vertical) 鼠标(垂直翻转) Mouse (Inverted Horizontal + Vertical) 鼠标(水平翻转 + 垂直翻转) Arrows 方向键 Keys: W | A | S | D 按键:W | A | S | D NumPad 数字键盘 None Standard 标准 Eight Way 八向 4 Way Cardinal 正四向 4 Way Diagonal 斜四向 Mouse Settings 鼠标设置 DPadEditDialog Dialog 对话框 Presets: 预设: Mouse (Normal) 鼠标(正常) Mouse (Inverted Horizontal) 鼠标(水平翻转) Mouse (Inverted Vertical) 鼠标(垂直翻转) Mouse (Inverted Horizontal + Vertical) 鼠标(水平翻转 + 垂直翻转) Arrows 方向键 Keys: W | A | S | D 按键:W | A | S | D NumPad 数字键盘 None Dpad Mode: 十字键模式: &Name: 名称 (&N): 4 Way Cardinal 正四向 4 Way Diagonal 斜四向 DPad Delay: 十字键延迟: Time lapsed before a direction change is taken into effect. 方向改变生效前的延迟。 s Specify the name of a dpad. 指定十字键的名称。 Mouse Settings 鼠标设置 Standard 标准 Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. 标准:十字键有八个区域。当十字键处于对角线区域时,两个方向的按键同时被激活。 八向:十字键有八个区域。每个区域有自己的方向按键。同一时间仅有一个方向按键被激活。尤其适用于类 Rouge 游戏。 正四向:十字键有四个区域,分别对应上下左右四个方向。尤其适用于菜单选择。 斜四向:十字键有四个区域,分别对应对角线的四个方向。 Eight Way 八向 Set 设置 Set %1 设置%1 EditAllDefaultAutoProfileDialog Default Profile 默认配置文件 Profile: 配置文件: Browse 浏览 Open Config 打开配置文件 Profile file path is invalid. 配置文件路径无效。 ExtraProfileSettingsDialog Extra Profile Settings 附加配置文件设置 Key Press Time: 按键按下时间: 0.00 ms 0.00毫秒 Profile Name: 配置文件名称: s GameController Game Controller 游戏控制器 GameControllerDPad DPad 十字键 GameControllerMappingDialog Game Controller Mapping 游戏控制器映射 <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> A A键 B B键 X X键 Y Y键 Back 后退键 Start 开始键 Guide 导航键 Left Shoulder 左肩键 Right Shoulder 右肩键 Left Stick Click 左摇杆点击 Right Stick Click 右摇杆点击 Left Stick X 左摇杆X轴 Left Stick Y 左摇杆Y轴 Right Stick X 右摇杆X轴 Right Stick Y 右摇杆Y轴 Left Trigger 左扳机 Right Trigger 右扳机 DPad Up 十字键上 DPad Left 十字键左 DPad Down 十字键下 DPad Right 十字键右 Mapping 映射 SDL 2 Game Controller Mapping String SDL 游戏控制器映射字符串 Last Axis Event: 最近轴事件: Current Axis Detection Dead Zone: 当前轴不灵敏区: 5000 5000 10000 10000 15000 15000 20000 20000 25000 25000 30000 30000 32000 32000 Game Controller Mapping (%1) (#%2) 游戏控制器映射 (%1) (#%2) Discard Controller Mapping? 放弃修改游戏控制器映射? Discard mapping for this controller? If discarded, the controller will be reverted to a joystick once you refresh all joysticks. 放弃修改这个游戏控制器的映射? 如果放弃,这个游戏控制器将在您刷新所有摇杆时被重新识别为一个摇杆。 GameControllerSet Back 后退键 Guide 导航键 Start 开始键 LS Click 左摇杆点击 RS Click 右摇杆点击 L Shoulder 左肩键 R Shoulder 右肩键 L Trigger 左扳机 R Trigger 右扳机 GameControllerTrigger Trigger 扳机 JoyAccelerometerButton Up Down Left Right Shock JoyAccelerometerSensor Accelerometer JoyAxis Axis JoyAxisButton Negative Positive Unknown 未知 Button 按钮 JoyAxisContextMenu Mouse (Horizontal) 鼠标(水平) Mouse (Inverted Horizontal) 鼠标(水平翻转) Mouse (Vertical) 鼠标(垂直) Mouse (Inverted Vertical) 鼠标(垂直翻转) Arrows: Up | Down 方向键:上|下 Arrows: Left | Right 方向键:左|右 Keys: W | S 按键:W | S Keys: A | D 按键:A | D NumPad: KP_8 | KP_2 数字键盘:8 | 2 NumPad: KP_4 | KP_6 数字键盘:4 | 6 None Mouse Settings 鼠标设置 Left Mouse Button 鼠标左键 Right Mouse Button 鼠标右键 JoyButton Processing turbo for #%1 - %2 正在处理按钮#%1-%2的连发 Finishing turbo for button #%1 - %2 正在完成按钮#%1-%2的连发 Distance change for button #%1 - %2 按钮#%1-%2距离改变 Button 按钮 [NO KEY] [无按键] [Set %1 1W] [单向选择设置%1] [Set %1 2W] [双向选择设置%1] [Set %1 WH] [按下时选择设置%1] JoyButtonContextMenu Toggle 开关 Turbo 连发 Clear 清除 Set Select 选择设置 Disabled 禁用 Set %1 设置%1 Set %1 1W 单向选择设置%1 Set %1 2W 双向选择设置%1 Set %1 WH 按下时选择设置%1 JoyButtonSlot Mouse 鼠标 Up Down Left Right LB 鼠标左键 MB 鼠标中键 RB 鼠标右键 Pause 暂停 Hold 按下 Cycle 周期 Distance 距离 Release 释放 Mouse Mod 鼠标变速 Press Time 按下时间 Delay 延迟 Load %1 载入%1 Set Change %1 设置改变%1 [Text] %1 [文本]%1 [Exec] %1 [运行]%1 [NO KEY] [无按键] JoyControlStick Stick 摇杆 JoyControlStickButton Up Down Left Right Button 按钮 JoyControlStickContextMenu Mouse (Normal) 鼠标(正常) Mouse (Inverted Horizontal) 鼠标(水平翻转) Mouse (Inverted Vertical) 鼠标(垂直翻转) Mouse (Inverted Horizontal + Vertical) 鼠标(水平翻转 + 垂直翻转) Arrows 方向键 Keys: W | A | S | D 按键:W | A | S | D NumPad 数字键盘 None Standard 标准 Eight Way 八向 4 Way Cardinal 正四向 4 Way Diagonal 斜四向 Mouse Settings 鼠标设置 JoyControlStickEditDialog Dialog 对话框 X: X轴: 0 0 Y: Y轴: Distance: 距离: Presets: 预设: Mouse (Normal) 鼠标(正常) Mouse (Inverted Horizontal) 鼠标(水平翻转) Mouse (Inverted Vertical) 鼠标(垂直翻转) Mouse (Inverted Horizontal + Vertical) 鼠标(水平翻转 + 垂直翻转) Arrows 方向键 Keys: W | A | S | D 按键:W | A | S | D NumPad 数字键盘 None Stick Mode: 摇杆模式: Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. 标准:摇杆有八个区域。当摇杆处于对角线区域时,两个方向的按键同时被激活。 八向:摇杆有八个区域。每个区域有自己的方向按键。同一时间仅有一个方向按键被激活。尤其适用于类 Rouge 游戏。 正四向:摇杆有四个区域,分别对应上下左右四个方向。尤其适用于菜单选择。 斜四向:摇杆有四个区域,分别对应对角线的四个方向。 4 Way Cardinal 正四向 4 Way Diagonal 斜四向 Modifier Zone: Dead zone value to use for an analog stick. 设置模拟摇杆的不灵敏区。 Value when an analog stick is considered moved 100%. 设置模拟摇杆的最大值。当达到这个值时,模拟摇杆被认为移动到了100%的位置。 The area (in degrees) that each diagonal region occupies. 每个对角线区域的角度数。 Square Stick: 方形摇杆: Percentage to modify a square stick coordinates to confine values to a circle 这个百分比用来调整方形摇杆的坐标值使其被限制在一个圆里 % % Stick Delay: 摇杆延迟: Time lapsed before a direction change is taken into effect. 方向改变生效前的延迟。 s Modifier: 修饰键: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. 编辑当摇杆被激活时同时激活的按钮。 这个按钮尤其适用于分配带有修饰键的区域,例如在模拟摇杆上分配行走/跑步的功能。 PushButton 按钮 Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Na&me: Name: 名称: Specify the name of an analog stick. 指定模拟摇杆的名称。 Mouse Settings 鼠标设置 Standard 标准 Bearing: 方向: % Safe Zone: 安全区(%): Eight Way 八向 Dead Zone: 不灵敏区: Max Zone: 最大区: Diagonal Range: 对角线区域范围: Set 设置 Set %1 设置%1 JoyControlStickModifierButton Modifier 修饰 JoyDPad DPad 十字键 JoyDPadButton Up Down Left Right Button 按钮 JoyGyroscopeButton Pitch Up Pitch Down Yaw Left Yaw Right Roll Left Roll Right JoyGyroscopeSensor Gyroscope JoySensorButton Button 按钮 JoySensorContextMenu Mouse Settings 鼠标设置 JoySensorEditDialog Dialog 对话框 0 0 Acceleration (m/s^2): Pitch (°): Roll (°): % Safe Zone: 安全区(%): Presets: 预设: Dead Zone: 不灵敏区: Dead zone value to use for an analog sensor. Max Zone: 最大区: Value when an analog sensor is considered moved 100%. Diagonal Range: 对角线区域范围: The area (in degrees) that each diagonal region occupies. 每个对角线区域的角度数。 Sensor Delay: Time lapsed before a direction change is taken into effect. 方向改变生效前的延迟。 s Na&me: Specify the name of an analog sensor. Mouse Settings 鼠标设置 Roll (°/s) Pitch (°/s) Yaw (°/s) Set 设置 Set %1 设置%1 JoySensorPreset None Mouse (Normal) 鼠标(正常) Mouse (Inverted Horizontal) 鼠标(水平翻转) Mouse (Inverted Vertical) 鼠标(垂直翻转) Mouse (Inverted Horizontal + Vertical) 鼠标(水平翻转 + 垂直翻转) Arrows 方向键 Keys: W | A | S | D 按键:W | A | S | D NumPad 数字键盘 JoyTabWidget <New> <新> Battery level of controller Remove 移除 Remove configuration from recent list. 从最近使用列表中移除配置。 Load 载入 Load configuration file. 载入配置文件。 Save 保存 Save changes to configuration file. 保存更改到配置文件。 Save As 另存为 Save changes to a new configuration file. 保存更改到新的配置文件。 Sets 设置 Copy from Set 从设置复制 Settings 设置 Set 1 设置1 Set 2 设置2 Set 3 设置3 Set 4 设置4 Set 5 设置5 Set 6 设置6 Set 7 设置7 Set 8 设置8 Stick/Pad Assign 摇杆/十字键分配 Controller Mapping 游戏控制器映射 Quick Set 快速设置 Names 名称 Toggle button name displaying. 开关按钮名称显示。 Pref 偏好设置 Change global profile settings. 改变全局配置文件设置。 Reset 重置 Revert changes to the configuration. Reload configuration file. 还原设置的更改。重新加载配置文件。 Open Config 打开配置文件 Config Files (*.amgp *.xml) 配置文件 (*.amgp *.xml) Config File (*.%1.amgp) 配置文件 (*.%1.amgp) Do you really want to reset buttons settings for joystick? 确定要重置所有按键设置吗? Save Profile Changes? 保存配置文件更改? Changes to the new profile have not been saved. Would you like to save or discard the current profile? 新配置文件的更改尚未保存。您想保存还是放弃修改当前的配置文件? Changes to the profile "%1" have not been saved. Would you like to save or discard changes to the current profile? 配置文件“%1”的更改尚未保存。您想保存还是放弃修改此配置文件? Sticks 摇杆 Sensors DPads 十字键 No buttons have been assigned. Please use Quick Set to assign keys to buttons or disable hiding empty buttons. 按钮未被分配。请使用“快速设置”来将按键分配到按钮,或取消隐藏空白按钮。 Set %1: %2 设置%1:%2 Set %1 设置%1 Copy Set Assignments 复制设置分配信息 Are you sure you want to copy the assignments and device properties from %1? 您确定要从 %1 复制分配信息和设备属性吗? Save Config 保存配置文件 Set 设置 Joystick Joystick 摇杆 JoystickStatusWindow Properties 属性 Details 详细信息 Name: 名称: %1 %1 Number: 编号: Axes: 轴数: Buttons: 按钮数: Hats: 帽子开关数: Sensors: Battery: 电量: Unknown 未知 GUID: 全局唯一标识符: Game Controller: 是否为手柄: Axes Buttons 按钮 Hats 帽子开关 Sensors %1 (#%2) Properties %1 (#%2) 属性 Empty Low Medium Full Wired Different: %1 Accelerometer + Gyroscope Accelerometer Gyroscope None Axis %1 轴%1 Hat %1 帽子开关%1 No Yes MainSettingsDialog Edit Settings 编辑设置 General 常规 Controller Mappings 游戏控制器映射 Language 语言 Auto Profile 自动配置文件 Mouse 鼠标 Advanced 高级选项 <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> <html><head/><body><p>指定本程序在加载或保存一个配置文件时,文件对话框中默认使用的路径。</p></body></html> Recent Profile Count: 最近使用的配置文件数: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> <html><head/><body><p>最近使用的配置文件列表中配置文件的数量。设为0将显示所有最近使用的配置文件。</p></body></html> Gamepad Poll Rate: 手柄轮询速率: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. 改变轮询速率来发现新的手柄事件。默认10毫秒。 降低轮询速率可能会导致本程序使用更多的处理器资源。请在以无人值守方式使用前测试此选项。 Hide main window when the main window close button is clicked instead of quitting the program. 点击关闭按钮时,最小化主窗口到系统托盘而不是退出程序。 Close To Tray 关闭时最小化到系统托盘 Launch At Windows Startup Windows 开机自启动 Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. 在系统托盘菜单中以单一列表显示所有游戏控制器的最近使用的配置文件。 默认是使用子菜单。 Single Profile List in Tray 系统托盘菜单中使用单一配置文件列表 Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. 使本程序最小化到任务栏。 如果可能,默认情况下本程序将最小化到系统托盘。 Minimize to Taskbar 最小化到任务栏 This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. 此选项将使本程序隐藏所有未分配槽的按钮。 您需要使用“快速设置”对话框来打开手柄按钮的编辑对话框。 Hide Empty Buttons 隐藏空白按钮 When the program is launched, open the last known profile that was opened during the previous session. 本程序启动时,打开上次使用的配置文件。 Auto Load Last Opened Profile 自动加载上次打开的配置文件 Only show the system tray icon when the program first launches. 首次启动本程序时只显示系统托盘。 Launch in Tray 启动时最小化到系统托盘 Associate Profiles 关联配置文件 Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Show low battery notification Show empty battery notification Key Repeat 键重复 Active keys will be repeatedly pressed when this option is enabled. 此选项启用后,处于活动状态的按键将一直被重复按下。 Enable 启用 Português do Brasil 巴西葡萄牙语 Français 法语 Deutsch 德语 Italiano 意大利语 日本語 日本语 Русский 俄语 српски / srpski 塞尔维亚语 Español 西班牙语 українська 乌克兰语 Polski History Si&ze: Weight Modi&fier: Log File: 日志文件: <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> Log Level: 日志级别: None Error 错误 Warning 警告 Info 信息 Verbose Debug 调试 Note: To see the change of log level in console output (not in log file), application restart is required Reset 重置 Class Pro&file Directory: 配置文件路径: Title 标题 Program 程序 Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. 在 AntiMicroX 运行时禁用 Windows 的“提高指针精确度”选项。 禁用“提高指针精确度”可使鼠标在开启 AntiMicroX 的情况下更精准地移动。 Disable Enhance Pointer Precision 禁用提高指针精确度 Smoothing 平滑 Refresh Rate: 刷新率: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. 刷新率是鼠标事件之间间隔的时间。 请小心修改此选项,因为它可能会导致本程序使用更多的处理器资源。 此选项的值过低可能会导致系统不稳定。 请在以无人值守方式使用前测试此选项。 Accel Numerator: 加速度分子: 0 0 Accel Denominator: 加速度分母: Accel Threshold: 加速度阈值: If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. 如果虚拟鼠标的加速度值被另一个进程改变,尤其是在退出老游戏的时候,您可能需要重置虚拟鼠标使用的加速度值。 Reset Acceleration 重置加速度 Delay: 延迟: Have Windows start AntiMicroX at system startup. 在 Windows 启动时运行本程序。 Associate .amgp files with AntiMicroX in Windows Explorer. 在 Windows 资源管理器中将 .amgp 文件关联到 AntiMicroX。 Specifies how much time should elapse before key repeating begins. 指定开始键重复之前的延迟时间。 ms 毫秒 Rate: 频率: Specifies how many times key presses will be performed per seconds. 指定每秒按键多少次。 times/s 次/秒 Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. 下面是已保存的自定义映射。您可以使用下表删除或临时禁用一个映射。您还可以禁用 SDL 中包含的映射。您只需要插入新的一行,指定摇杆的全局统一标识符,然后勾选禁用。 设置仅在您刷新所有摇杆或者拔出那个被禁用的摇杆之后生效。 GUID 全局唯一标识符 Mapping String 映射字符串 Disable? 禁用? Delete 删除 <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> <html><head/><body><p>AntiMicroX 已被贡献者翻译为多种语言。默认情况下,本程序将根据您系统的区域设置选择相应的语言。然而,您也可以让 AntiMicroX 加载以下列表中的任意语言。</p></body></html> Default 默认 English 英语 简体中文 简体中文 Active 启用 Devices: 设备: All 所有 Device 设备 Profile 配置文件 Default? 默认? Add 添加 Edit 编辑 Spring 弹簧 Screen: 屏幕: Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. 在弹簧模式中使用指定的屏幕。 在 Linux 系统上,默认使用主屏幕。 在 Windows 系统上,默认使用所有可用屏幕。 AutoProfile (disabled in Wayland) Also, Windows users who want to use a low value should also check the "Disable Enhance Pointer Precision" checkbox if you haven't disabled the option in Windows. 另外,对于希望使用较低值的 Windows 用户,如果您未禁用 Windows 的“提高指针精确度”选项,请勾选本程序中的“禁用提高指针精确度”复选框。 Select Default Profile Directory 选择默认配置文件目录 Are you sure you want to delete the profile? 您确认要删除这个配置文件吗? Save Log File As 日志文件另存为 Log Files (*.log) 日志文件 (*.log) Do you really want to reset setting? 确定要重置设置吗? Would you like to reset mappings too? 是否需要重置按键映射? MainWindow AntiMicroX AntiMicroX No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu 未找到摇杆。 请插入一个摇杆然后选择“选项”菜单下的“更新摇杆” If events are not seen by a game, please click here to run this application as Administrator. 如果游戏无法检测到事件,请单击这里以管理员身份运行。 Update Button &App 程序 (&A) &Options 选项 (&O) He&lp 帮助 &Quit 退出 (&Q) Ctrl+Q Ctrl+Q &Update Joysticks 更新摇杆 (&U) Ctrl+U Ctrl+U &Hide 隐藏 (&H) Ctrl+H Ctrl+H &About 关于 (&A) Ctrl+A Ctrl+A About &Qt 关于&Qt Ctrl+T &Properties 属性 Ctrl+P &Key Checker 按键检查器 Ctrl+K &GitHub Page Ctrl+G S&ettings 设置 Ctrl+S &Stick/Pad Assign Ctrl+X &Wiki Ctrl+W &Issues Ctrl+I &Calibration 校准... Ctrl+C Home Page 主页 (%1) (%1) Open File 打开文件 Are you sure that you want to run this program as Adminstrator? Some games run as Administrator which will cause events generated by antimicro to not be used by those games unless antimicro is also run as the Adminstrator. This is due to permission problems caused by User Account Control (UAC) options in Windows Vista and later. %1 battery %1 电量 Battery level is less than %1 电池电量已低于 %1 Device number: %1 Device name: %2 Update to %1 available Reading old profile 读取旧的配置文件 This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25 &Restore 还原 (&R) Calibration couldn't be opened 无法进行校准 You must connect at least one controller to open the window 至少要连接一个控制器才能使用校准功能 Run as Administrator? 以管理员权限运行? Failed to elevate program 无法提升本程序权限 Failed to restart this program as the Administrator 无法以管理员权限重新运行本程序 MouseAxisSettingsDialog Mouse Settings - 鼠标设置 - Set %1 设置%1 MouseButtonSettingsDialog Mouse Settings - 鼠标设置 - Set %1 设置%1 MouseControlStickSettingsDialog Mouse Settings 鼠标设置 Set %1 设置%1 MouseDPadSettingsDialog Mouse Settings 鼠标设置 Set %1 设置%1 MouseSensorSettingsDialog Mouse Settings 鼠标设置 Set %1 设置%1 MouseSettingsDialog Mouse Settings 鼠标设置 Mouse Mode: 鼠标模式: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. 光标:移动时,鼠标光标以当前位置为基准,移动距离取决于您移动轴或按下按钮的幅度。 弹簧:移动时,鼠标光标以屏幕中心为基准,移动距离取决于您移动轴的幅度。轴移回不灵敏区之后,鼠标光标将回到屏幕中心。 Cursor 光标 Spring 弹簧 Acceleration: 加速模式: Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. 增强精度:三级曲线使得鼠标光标在轴移动幅度较小时移动慢,轴移动幅度较大时移动快。 线性:鼠标移动速度和轴移动幅度成比例。 平方:鼠标光标在轴移动幅度较小时缓慢加速。 立方:鼠标加速度比平方模式慢。 极限平方:轴移动距离达到95%后提升1.5倍鼠标速度。 指数函数:允许更多自定义曲线选项。 平方缓动:轴移动幅度较大时,鼠标速度随时间以平方曲线增加。 立方缓动:轴移动幅度较大时,鼠标速度随时间以立方曲线增加。 Enhanced Precision 增强精度 Linear 线性 Quadratic 平方 Cubic 立方 Quadratic Extreme 极限平方 Power Function 指数函数 Easing Quadratic 平方缓动 Easing Cubic 立方缓动 Mouse Speed Settings 鼠标速度设置 Enable to change the horizontal and vertical speed boxes at the same time. 同时改变水平和垂直速度。 Change Together 同时更改 Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. 在加速曲线之上为鼠标移动增添额外加速。 加速度基于手柄在一次采样时间内轴移动的速度。 这些选项是为了绕过某些由于手柄模拟摇杆的输入范围有限所带来的问题。 Delta Acceleration 额外加速 &Multiplier: 倍数 (&M): Mi&n Threshold: 最小阈值 (&N): E&xtra Duration: 额外加速时长 (&X): 1 = 20 pps 1级=20像素/秒 Wheel Hori. Speed: 滚轮水平速度: Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. 根据每秒模拟滚动凹槽数设置鼠标滚轮水平滚动速度。 Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. 根据每秒模拟滚动凹槽数设置鼠标滚轮垂直滚动速度。 Sensitivit&y: 灵敏度 (&Y): For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. 仅用于指数函数加速曲线。 指定曲线敏感度系数。当该值大于1.0时,增大轴移动幅度较小时的鼠标加速度。 Easing Duration: 缓动时长: Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. 轴移动幅度达到最大后,鼠标在此时长(以秒为单位)内加速到最大速度。 s Highest value to accelerate mouse movement by 鼠标速度的最大加速值 x x Start %: 起始百分比: Acceleration begins at this percentage of the base multiplier 加速以基础倍数的此百分比速率开始 % % Minimum amount of axis travel required for acceleration to begin 轴的移动幅度大于此最小阈值之后加速才开始 Max Threshold: 最大阈值: Maximum axis travel before acceleration has reached the multiplier value 轴的移动幅度达到此最大阈值时加速达到上述倍数值 Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. 此期间内额外加速生效。 轴的移动幅度考虑在内。缓慢的轴移动将减小实际的额外加速生效时间。 Curve: 曲线: Ease Out Sine 正弦滑出缓动 Ease Out Quad 平方滑出缓动 Ease Out Cubic 立方滑出缓动 Release Radius: 释放半径: Specifies that the spring area will be relative to the mouse position set by a non-relative spring. 弹簧区域将相对于鼠标指针的位置。鼠标指针的位置可由其它非弹簧模式指定。 Relative 相对 Mouse Status 鼠标状态 X: X轴: 0 (0 pps) 0(0像素/秒) Y: Y轴: 1 = 1 notch(es)/s 1级=1凹槽/秒 Hori&zontal Speed: 水平速度 (&Z): &Vertical Speed: 垂直速度 (&V): Wheel Vert. Speed: 滚轮垂直速度: Spring Settings 弹簧设置 Spring Width: 弹簧区域宽度: Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. 设置鼠标以弹簧模式移动的区域的宽度。设为0时将使用您整个屏幕的宽度。 Spring Height: 弹簧区域高度: Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. 设置鼠标以弹簧模式移动的区域的高度。设为0时将使用您整个屏幕的高度。 %n notch(es)/s %n凹槽/秒 QKeyDisplayDialog Key Checker 按键检查器 <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Event Handler: 事件处理程序: Native Key Value: 系统原生键值: 0x00000000 0x00000000 Qt Key Value: Qt 原始键值: antimicro Key Value: QObject Super Super Menu Menu Mute Mute Vol+ Vol+ Vol- Vol- Play/Pause Play/Pause Play Play Pause Pause Prev Prev Next Next Mail Mail Home Home Media Media Search Search Your original settings (previously stored in %1) have been copied to %2 If you want you can delete the original directory or leave it as it is. Some problem with settings migration occurred. Original configs are stored in %1 but their new location is: %2 You can migrate manually by renaming old directory and renaming file to antimicrox_settings.ini. Quitting Program 正在退出程序 # of joysticks found: %1 已发现摇杆数:%1 List Joysticks: 摇杆列表: --------------- --------------- Joystick %1: 摇杆%1: Attempting to use fallback option %1 for event generation. 尝试为事件生成使用后备选项 %1。 Failed to open event generator. Exiting. 无法打开事件发生器。正在退出。 Using %1 as the event generator. 使用 %1 作为事件发生器。 Last button There isn't a last button pressed from gamepad in data. Did you set at least one button from gamepad for keyboard? Unknown log level: Specified contradicting flags: --show and --hidden Profile location %1 is not an XML file. 配置文件 %1 不是一个 XML 文件。 Profile location %1 does not exist. 配置文件 %1 不存在。 Controller identifier is not a valid value. 游戏控制器标识符无效。 An invalid set number '%1' was specified. 指定的设置编号 "%1" 无效。 Controller identifier '%s'' is not a valid value. 游戏控制器标识符 "%s" 无效。 No set number was specified. 未指定设置编号。 An invalid event generator was specified. 指定的事件发生器无效。 No event generator string was specified. 未指定事件发生器字符串。 No log file specified. 未指定日志文件。 xinput version must be at least 2.0. No mouse acceleration changes will occur. XInput 版本必需至少为2.0。鼠标加速选项将无效。 Unable to open uinput files, this may cause problems with generating events. To check possible solutions please visit: QuickSetDialog Quick Set 快速设置 <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> <html><head/><body><p>请在 %1(<span style=" font-weight:600;">%2</span>)上按任意键或移动任意轴。<br/>之后一个对话框会弹出并允许您设置按键分配。</p></body></html> Quick Set %1 快速设置 %1 SetAxisThrottleDialog Throttle Change 阀设置改变 The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? 轴%1的阀设置已改变。 您想将这个阀设置的改变应用到所有设置吗? SetJoystick Set %1: %2 设置%1:%2 Set %1 设置%1 SetNamesDialog Set Name Settings 指定设置名称 Set 1 设置1 Set 2 设置2 Set 3 设置3 Set 4 设置4 Set 5 设置5 Set 6 设置6 Set 7 设置7 Set 8 设置8 Name 名称 SimpleKeyGrabberButton Mouse 鼠标 SpringModeRegionPreview Spring Mode Preview 弹簧模式预览 UInputEventHandler Could not find a valid uinput device file. Please check that you have the uinput module loaded. lsmod | grep uinput 无法找到任何有效的 uinput 设备文件。 请确认您加载了 uinput 模块: lsmod | grep uinput Could not open uinput device file Please check that you have permission to write to the device 无法打开 uinput 设备文件 请确认您有写入该设备的权限 Using uinput device file %1 使用 uinput 设备文件%1 UInputHelper a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z Esc Esc F1 F1 F2 F2 F3 F3 F4 F4 F5 F5 F6 F6 F7 F7 F8 F8 F9 F9 F10 F10 F11 F11 F12 F12 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 ` ` 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 - - = = BackSpace BackSpace Tab Tab [ [ ] ] \ \ CapsLock CapsLock ; ; ' ' Enter Enter Shift_L Shift_L , , . . / / Ctrl_L Ctrl_L Super_L Super_L Alt_L Alt_L Space Space Alt_R Alt_R Menu Menu Ctrl_R Ctrl_R Shift_R Shift_R Up Up Left Left Down Down Right Right PrtSc PrtSc Ins Ins Del Del Home Home End End PgUp PgUp PgDn PgDn NumLock NumLock * * + + KP_Enter KP_Enter KP_1 KP_1 KP_2 KP_2 KP_3 KP_3 KP_4 KP_4 KP_5 KP_5 KP_6 KP_6 KP_7 KP_7 KP_8 KP_8 KP_9 KP_9 KP_0 KP_0 SCLK SCLK Pause Pause Super_R Super_R Mute Mute VolDn VolDn VolUp VolUp Play Play Stop Stop Prev Prev Next Next [NO KEY] [无按键] UnixWindowInfoDialog Captured Window Properties 捕获的窗口属性 Information About Window 窗口信息 Class: 类: TextLabel 文本标签 Title: 标题: Path: 路径: Match By Properties 根据属性匹配 Class Title 标题 Path 路径 VDPad VDPad 虚拟十字键 VirtualKeyPushButton Space Space Tab Tab Shift (L) Shift (L) Shift (R) Shift (R) Ctrl (L) Ctrl (L) Ctrl (R) Ctrl (R) Alt (L) Alt (L) Alt (R) Alt (R) Alt Gr ` ` ~ ~ - - = = [ [ ] ] \ \ Caps Caps ; ; ' ' , , . . / / ESC ESC PRTSC PRTSC SCLK SCLK INS INS PGUP PGUP DEL DEL PGDN PGDN 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 0 0 NUM LK NUM LK * * + + Enter Enter Del Del < < : : Super (L) Super (L) Menu Menu Up Up Down Down Left Left Right Right VirtualKeyboardMouseWidget Keyboard 键盘 Mouse 鼠标 Mouse Settings 鼠标设置 Left Mouse Up Mouse Left Button Mouse 左键 Middle Button Mouse 中键 Right Button Mouse 右键 Wheel Up Mouse 滚轮向上 Wheel Left Mouse 滚轮向左 Wheel Right Mouse 滚轮向右 Wheel Down Mouse 滚轮向下 Down Mouse Right Mouse Button 4 Mouse 按钮4 Mouse 8 Mouse 按钮8 Button 5 Mouse 按钮5 Mouse 9 Mouse 按钮9 NONE [NO KEY] [无按键] Last button Slots for button couldn't be cleared, because there was not any set button from keyboard for gamepad. Map at least one button from keyboard to gamepad Others 其他按键 Applications 应用程序 Browser Back 浏览器后退 Browser Favorites 浏览器收藏 Browser Forward 浏览器前进 Browser Home 浏览器主页 Browser Refresh 浏览器刷新 Browser Search 浏览器搜索 Browser Stop 浏览器停止 Calc 计算器 Email 邮件 F13 F13 F14 F14 F15 F15 F16 F16 F17 F17 F18 F18 F19 F19 F20 F20 F21 F21 F22 F22 F23 F23 F24 F24 Media 多媒体 Media Next 多媒体下一首 Media Play 多媒体播放 Media Previous 多媒体上一首 Media Stop 多媒体停止 Search 搜索 Volume Down 音量减小 Volume Mute 静音 Volume Up 音量增加 VirtualMousePushButton INVALID 无效 WinAppProfileTimerDialog Capture Application 捕捉应用程序 After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. 按下“捕捉应用程序”按钮之后,请选择您想要关联配置文件的应用程序窗口。活动的应用程序将在指定的秒数之后被捕捉。 Timer: 计时器: Seconds Cancel 取消 WinExtras [NO KEY] [无按键] AntiMicro Profile X11Extras ESC ESC Tab Tab Space Space DEL DEL Return Return KP_Enter KP_Enter Backspace Backspace Alt Gr xinput extension was not found. No mouse acceleration changes will occur. 未找到 XInput 扩展。鼠标加速选项将无效。 xinput version must be at least 2.0. No mouse acceleration changes will occur. XInput 版本必需至少为2.0。鼠标加速选项将无效。 PtrFeedbackClass was not found for virtual pointer.No change to mouse acceleration will occur for device with id=%1 未找到虚拟指针的 PtrFeedbackClass。鼠标加速选项在 ID=%1 的设备上将无效 Changing mouse acceleration for device with id=%1 正在改变 ID=%1 的设备上的鼠标加速选项 XMLConfigReader Could not write updated profile XML to file %1. 无法将更新后的配置 XML 写入文件 %1。 XMLConfigWriter Could not write to profile at %1. 无法写入配置文件 %1。 antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. main Launch program in system tray only. 启动后最小化到系统托盘。 Launch program with the tray menu disabled Launch program without the main window displayed Show app window when hidden. (Used for unhiding window of already running app instance). Launch program with the configuration file selected as the default for selected controllers, or change active profile of running app. Defaults to all controllers location Apply configuration file to a specific controller. Value can be a controller index, name, or GUID value Unload currently enabled profile(s) value(s) Start joysticks on a specific set. Value can be a controller index, name, or GUID number value Enable logging. Levels (from the least strict): warn,info,verbose,debug log-type Choose a file for logs writing filename 文件名 Choose between using XTest support and uinput support for event generation. Use only if you have enabled xtest and uinput options on Linux or vmulti on Windows. Default: xtest. event-generation-type Print information about joysticks detected by SDL. Use only if you have sdl library. You can check your controller index, name or even GUID. AntiMicroX-antimicrox-b300273/share/gamecontrollerdb_linux.txt000066400000000000000000004203471471077622000245710ustar00rootroot00000000000000# Game Controller DB for SDL in 2.0.16 format # Source: https://github.com/gabomdq/SDL_GameControllerDB # Linux 030000005e0400008e02000020010000,8BitDo Adapter,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c82d00000031000011010000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00000951000000010000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, 03000000021000000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00001251000011010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00001251000000010000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00001151000011010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00001151000000010000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000151000000010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00000650000011010000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,platform:Linux, 05000000c82d00005106000000010000,8BitDo M30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00000451000000010000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,start:b11,platform:Linux, 03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000008000000210000011010000,8BitDo NES30,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 03000000c82d00000310000011010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux, 05000000c82d00008010000000010000,8BitDo NES30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b9,righttrigger:b8,start:b11,x:b3,y:b4,platform:Linux, 03000000022000000090000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000190000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000751000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000c82d00000851000000010000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:a8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00000660000011010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000131000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000231000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000331000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000431000011010000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00002867000000010000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b3,y:b4,platform:Linux, 05000000c82d00000060000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 030000003512000012ab000010010000,8BitDo SFC30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Linux, 030000003512000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d000021ab000010010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, 05000000102800000900000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00003028000000010000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000351000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00001290000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00006228000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 05000000202800000900000000010000,8BitDo SNES30,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, 05000000a00500003232000001000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, 05000000a00500003232000008010000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux, 03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux, 050000005e040000e002000030110000,8BitDo Zero 2,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, 05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux, 03000000c01100000355000011010000,Acrux Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e00003901000000430000,Afterglow Prismatic Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00003901000013020000,Afterglow Prismatic Controller 048-007-NA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00001302000000010000,Afterglow Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00003901000020060000,Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000100000008200000011010000,Akishop Customs PS360,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000007c1800000006000010010000,Alienware Dual Compatible Game PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Linux, 05000000491900000204000021000000,Amazon Fire Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Linux, 05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 03000000a30c00002700000011010000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000a30c00002800000011010000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, 05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Linux, 03000000050b00000579000011010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b36,paddle1:b52,paddle2:b53,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000050b00000679000000010000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b21,paddle1:b22,paddle2:b23,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, 03000000503200000110000011010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, 05000000503200000110000000000000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, 05000000503200000110000044010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, 05000000503200000110000046010000,Atari Classic Controller,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,platform:Linux, 03000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux, 03000000503200000210000011010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, 05000000503200000210000000000000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, 05000000503200000210000045010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, 05000000503200000210000046010000,Atari Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Linux, 05000000503200000210000047010000,Atari VCS Modern Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:-a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,platform:Linux, 03000000c62400001b89000011010000,BDA MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000c21100000791000011010000,Be1 GC101 Controller 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000c31100000791000011010000,Be1 GC101 Controller 1.03,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000005e0400008e02000003030000,Be1 GC101 Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 05000000bc2000000055000001000000,BETOP AX1 BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000bc2000006412000011010000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b30,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000006b1400000209000011010000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000666600006706000000010000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux, 03000000120c0000200e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000120c0000210e000011010000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux, 03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Linux, 03000000a306000022f6000011010000,Cyborg V3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000791d00000103000010010000,Dual Box Wii Classic Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000c11100000191000011010000,EasySMX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000242f00009100000000010000,EasySMX ESM-9101,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006e0500000320000010010000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, 030000006e0500000720000010010000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux, 030000007d0400000640000010010000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Linux, 03000000430b00000300000000010000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Linux, 03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000ac0500005b05000010010000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000558500001b06000010010000,GameSir G4 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000ac0500002d0200001b010000,GameSir G4s,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b33,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000bc2000005656000011010000,GameSir T4w,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000008f0e00000800000010010000,Gasia PlayStation Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000451300000010000010010000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000f0250000c183000010010000,Goodbetterbest Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000007d0400000540000000010000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 03000000280400000140000000010000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000008f0e00000610000000010000,GreenAsia Electronics Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Linux, 030000008f0e00001200000010010000,GreenAsia Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, 0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000f0250000c383000010010000,GT VX2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 06000000adde0000efbe000002010000,Hidromancer Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d81400000862000011010000,HitBox PS3 PC Analog Mode,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux, 03000000c9110000f055000011010000,HJC Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000632500002605000010010000,HJDX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000000d0f00000d00000000010000,Hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux, 030000000d0f00006d00000020010000,Hori EDGE 301,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:+a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000000d0f00005f00000011010000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00005e00000011010000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00005001000009040000,Hori Fighting Commander OCTA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000000d0f00008500000010010000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00008600000002010000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 030000000d0f00008800000011010000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00008700000011010000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,rightstick:b11,righttrigger:a4,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00001000000011010000,Hori Fightstick 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 03000000ad1b000003f5000033050000,Hori Fightstick VX,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b8,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, 030000000d0f00004d00000011010000,Hori Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000000d0f00003801000011010000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Linux, 030000000d0f00009200000011010000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f0000aa00000011010000,Hori Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000000d0f00001100000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00002200000011010000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00006a00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00006b00000011010000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00001600000000010000,Hori Real Arcade Pro EXSE,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, 030000000d0f00006e00000011010000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00006600000011010000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f0000ee00000011010000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000000d0f00006700000001010000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000000d0f0000c100000011010000,Horipad S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 050000000d0f0000f600000001000000,Horipad Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000341a000005f7000010010000,HuiJia GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux, 030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Linux, 03000000242e00008816000001010000,Hyperkin X91,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, 050000006964726f69643a636f6e0000,idroidcon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000b50700001503000010010000,Impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, 03000000d80400008200000003000000,IMS PCU0,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,platform:Linux, 03000000120c00000500000010010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, 03000000ef0500000300000000010000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Linux, 03000000fd0500000030000000010000,InterAct GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Linux, 03000000fd0500002a26000000010000,InterAct HammerHead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux, 0500000049190000020400001b010000,Ipega PG 9069,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b161,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000632500007505000011010000,Ipega PG 9099,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 0500000049190000030400001b010000,Ipega PG9099,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000491900000204000000000000,Ipega PG9118,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000300f00001001000010010000,Jess Tech Dual Analog Rumble,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, 03000000300f00000b01000010010000,Jess Tech GGE909 PC Recoil,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, 03000000ba2200002010000001010000,Jess Technology Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, 030000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux, 050000007e0500000620000001000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Linux, 030000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux, 050000007e0500000720000001000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Linux, 03000000bd12000003c0000010010000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000242f00002d00000011010000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000242f00008a00000011010000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, 030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d040000d1ca000000000000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d0400001dc2000014400000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d0400001ec2000019200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d0400001ec2000020200000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d04000019c2000011010000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d0400001fc2000005030000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux, 030000006d0400000ac2000010010000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Linux, 05000000380700006652000025010000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700008532000010010000,Mad Catz Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 03000000380700005032000011010000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700005082000011010000,Mad Catz Fightpad Pro PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux, 03000000380700008034000011010000,Mad Catz Fightstick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700008084000011010000,Mad Catz Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000380700008433000011010000,Mad Catz Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700008483000011010000,Mad Catz Fightstick TE S PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000380700001888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700003888000010010000,Mad Catz Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000380700001647000010040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000380700003847000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000120c00000500000000010000,Manta Dualshock 2,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, 03000000790000004318000010010000,Mayflash GameCube Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, 03000000790000004418000010010000,Mayflash GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, 03000000242f00007300000011010000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b0,y:b3,platform:Linux, 0300000079000000d218000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000d620000010a7000011010000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000242f0000f700000001010000,Mayflash Magic S Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 0300000025090000e803000001010000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:a5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, 03000000790000000318000011010000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Linux, 03000000b50700001203000010010000,Mega World Logic 3 Controller,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, 03000000780000000600000010010000,Microntek Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 030000005e0400002800000000010000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Linux, 030000005e0400000e00000000010000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux, 030000005e0400000700000000010000,Microsoft SideWinder Gamepad,a:b0,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Linux, 030000005e0400002700000000010000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Linux, 030000005e0400008502000000010000,Microsoft Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, 030000005e0400008e02000001000000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.1,dpleft:h0.2,dpright:h0.8,dpup:h0.4,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000004010000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000056210000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000062230000,Microsoft Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000120b00000b050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000d102000001010000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000d102000003020000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 060000005e040000120b000009050000,Microsoft Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000dd02000003020000,Microsoft Xbox One 2015,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000e302000003020000,Microsoft Xbox One Elite,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000000b000008040000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000005e040000050b000003090000,Microsoft Xbox One Elite 2,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000005e040000ea02000008040000,Microsoft Xbox One S,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008902000021010000,Microsoft Xbox pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, 03000000030000000300000002000000,Miroof,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux, 050000004d4f435554452d3035335800,Mocute 053X,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 050000004d4f435554452d3035305800,Mocute 054X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000d6200000e589000001000000,Moga 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 05000000d62000007162000001000000,Moga Pro 2,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux, 03000000c62400002b89000011010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000c62400002a89000000010000,MOGA XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000c62400001a89000000010000,MOGA XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000250900006688000000010000,MP8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, 030000005e0400008e02000010020000,MSI GC20 V2,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006b1400000906000014010000,Nacon Asymmetric Wireless PS4 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006b140000010c000010010000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 03000000853200000706000012010000,Nacon GC-100,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000000d0f00000900000010010000,Natec Genesis P44,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000004f1f00000800000011010000,NeoGeo PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 0300000092120000474e000000010000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Linux, 03000000790000004518000010010000,Nexilux GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Linux, 030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Linux, 060000007e0500003713000000000000,Nintendo 3DS,a:b0,b:b1,back:b8,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, 030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux, 03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b2,y:b3,platform:Linux, 060000007e0500000620000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 060000007e0500000820000000000000,Nintendo Switch Combined Joy-Cons,a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 050000004c69632050726f20436f6e00,Nintendo Switch Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b16,b:b15,back:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b14,y:b17,platform:Linux, 03000000d620000013a7000011010000,Nintendo Switch PowerA Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,back:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b0,y:b3,platform:Linux, 05000000010000000100000003000000,Nintendo Wii Remote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, 030000000d0500000308000010010000,Nostromo n45 Dual Analog,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux, 050000007e0500001920000001000000,NSO N64 Controller,+rightx:b8,+righty:b7,-rightx:b3,-righty:b2,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Linux, 050000007e0500001720000001000000,NSO SNES Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux, 03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux, 05000000550900001472000001000000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Linux, 03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 19000000010000000100000001010000,ODROID Go 2,a:b1,b:b0,dpdown:b7,dpleft:b8,dpright:b9,dpup:b6,guide:b10,leftshoulder:b4,leftstick:b12,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b13,righttrigger:b14,start:b15,x:b2,y:b3,platform:Linux, 19000000010000000200000011000000,ODROID Go 2,a:b1,b:b0,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b12,leftshoulder:b4,leftstick:b14,lefttrigger:b13,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:b16,start:b17,x:b2,y:b3,platform:Linux, 03000000c0160000dc27000001010000,OnyxSoft Dual JoyDivision,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:Linux, 05000000362800000100000002010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, 05000000362800000100000003010000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux, 05000000362800000100000004010000,OUYA Controller,a:b0,b:b3,back:b14,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b16,x:b1,y:b2,platform:Linux, 03000000830500005020000010010000,Padix Rockfire PlayStation Bridge,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Linux, 03000000ff1100003133000010010000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000006f0e0000b802000001010000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e0000b802000013020000,PDP Afterglow Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e0000d702000006640000,PDP Black Camo Wired Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:b13,dpleft:b14,dpright:b13,dpup:b14,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00003101000000010000,PDP EA Sports Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00008001000011010000,PDP Faceoff Nintendo Switch Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e0000c802000012010000,PDP Kingdom Hearts Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00008501000011010000,PDP Nintendo Switch Fightpad Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000006f0e00002801000011010000,PDP PS3 Rock Candy Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e00008701000011010000,PDP Rock Nintendo Switch Candy Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000006f0e00000901000011010000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e0000a802000023020000,PDP Xbox One Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 030000006f0e0000a702000023020000,PDP Xbox One Raven Black,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000004c050000da0c000011010000,PlayStation Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000d9040000160f000000010000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, 030000004c0500003713000011010000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d62000000140000001010000,PowerA Fusion Pro 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c62400001a53000000010000,PowerA Mini Pro Ex,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000c62400001a58000001010000,PowerA Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d62000000220000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, 03000000d62000000228000001010000,PowerA Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c62400001a54000001010000,PowerA Xbox One Mini Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d62000000240000001010000,PowerA Xbox One Spectra Infinity,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, 030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, 030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 030000005f1400003102000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000006f0e00001402000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000008f0e00000300000010010000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 050000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, 050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, 050000004c0500006802000000800000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 050000004c0500006802000000810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 05000000504c415953544154494f4e00,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, 060000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux, 030000004c050000a00b000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000004c050000a00b000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000004c050000c405000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000004c050000cc09000011810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 03000000c01100000140000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 050000004c050000c405000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 050000004c050000c405000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, 030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Linux, 050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux, 03000000300f00001211000011010000,Qanba Arcade Joystick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,platform:Linux, 03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000300f00001210000010010000,Qanba Joystick Plus,a:b0,b:b1,back:b8,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,start:b9,x:b2,y:b3,platform:Linux, 03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000009b2800000300000001010000,Raphnet 4nes4snes,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux, 030000009b2800004200000001010000,Raphnet Dual NES Adapter,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Linux, 030000009b2800003200000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, 030000009b2800006000000001010000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Linux, 030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000321500000204000011010000,Razer Panthera PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000104000011010000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000810000011010000,Razer Panthera PS4 Evo Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000010000011010000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000507000000010000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000321500000a10000001000000,Razer Raiju Tournament Edition,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000321500000011000011010000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000008916000000fe000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c6240000045d000024010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, 050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, 0300000032150000030a000001010000,Razer Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000790000001100000010010000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Linux, 0300000081170000990a000001010000,Retronic Adapter,a:b0,leftx:a0,lefty:a1,platform:Linux, 0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, 00000000526574726f53746f6e653200,RetroStone 2 Controller,a:b1,b:b0,back:b10,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,platform:Linux, 030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000006b140000130d000011010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e00001f01000000010000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000c6240000fefa000000010000,Rock Candy Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000a306000023f6000011010000,Saitek Cyborg V1 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000a30600001005000000010000,Saitek P150,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b7,lefttrigger:b6,rightshoulder:b2,righttrigger:b5,x:b3,y:b4,platform:Linux, 03000000a30600000701000000010000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Linux, 03000000a30600000cff000010010000,Saitek P2500 Force Rumble,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b0,y:b1,platform:Linux, 03000000a30600000c04000011010000,Saitek P2900,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux, 03000000a306000018f5000010010000,Saitek P3200 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000300f00001201000010010000,Saitek P380,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux, 03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux, 03000000a30600000b04000000010000,Saitek P990 Dual Analog,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Linux, 03000000a306000020f6000011010000,Saitek PS2700 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux, 03000000d81d00000e00000010010000,Savior,a:b0,b:b1,back:b8,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b9,x:b4,y:b5,platform:Linux, 03000000a30c00002500000011010000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Linux, 03000000790000001100000011010000,Sega Saturn,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b4,start:b9,x:b0,y:b3,platform:Linux, 03000000790000002201000011010000,Sega Saturn,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,start:b9,x:b2,y:b3,platform:Linux, 03000000b40400000a01000000010000,Sega Saturn,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Linux, 030000001f08000001e4000010010000,SFC Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000632500002305000010010000,ShanWan Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000f025000021c1000010010000,Shanwan Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000632500007505000010010000,Shanwan PS3 PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000bc2000000055000010010000,Shanwan PS3 PC ,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000341a00000908000010010000,SL6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 050000004c050000cc09000001000000,Sony DualShock 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000ff000000cb01000010010000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, 03000000250900000500000000010000,Sony PS2 pad with SmartJoy Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, 030000005e0400008e02000073050000,Speedlink Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000020200000,SpeedLink Xeox Pro Analog,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000d11800000094000011010000,Stadia Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, 03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, 03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b16,paddle2:b15,rightshoulder:b7,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux, 03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux, 03000000de2800000512000010010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,platform:Linux, 03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000004e696d6275732b0000000000,SteelSeries Nimbus Plus,a:b0,b:b1,back:b10,guide:b11,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Linux, 03000000381000003014000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000381000003114000075010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000ad1b000038f0000090040000,Street Fighter IV Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000003b07000004a1000000010000,Suncom SFX Plus,a:b0,b:b2,back:b7,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Linux, 03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux, 0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux, 030000008f0e00000d31000010010000,SZMY Power 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000457500000401000011010000,SZMY Power DS4 Wired Controller,a:b1,b:b2,x:b0,y:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:b6,platform:Linux, 03000000457500002211000010010000,SZMY Power Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 030000008f0e00001431000010010000,SZMY Power PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 03000000ba2200000701000001010000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Linux, 03000000790000001c18000011010000,TGZ Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, 030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, 030000004f04000020b3000010010000,Thrustmaster Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, 030000004f04000023b3000000010000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000004f0400000ed0000011010000,Thrustmaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000b50700000399000000010000,Thrustmaster Firestorm Digital 2,a:b2,b:b4,back:b11,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b0,righttrigger:b9,start:b1,x:b3,y:b5,platform:Linux, 030000004f04000003b3000010010000,Thrustmaster Firestorm Dual Analog 2,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b9,rightx:a2,righty:a3,x:b1,y:b3,platform:Linux, 030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux, 030000004f04000004b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, 030000004f04000026b3000002040000,Thrustmaster GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c6240000025b000002020000,Thrustmaster GPX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000004f04000008d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 030000004f04000009d0000000010000,Thrustmaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000004f04000007d0000000010000,Thrustmaster T Mini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux, 030000004f04000012b3000010010000,Thrustmaster Vibrating Gamepad,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux, 03000000571d00002000000010010000,Tomee SNES Adapter,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Linux, 03000000bd12000015d0000010010000,Tomee SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux, 03000000d814000007cd000011010000,Toodles 2008 Chimp PC PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux, 030000005e0400008e02000070050000,Torid,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000c01100000591000011010000,Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000680a00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, 03000000780300000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, 03000000e00d00000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, 03000000f00600000300000003000000,TRBot Virtual Joypad,a:b11,b:b12,back:b15,dpdown:b6,dpleft:b3,dpright:b4,dpup:b5,leftshoulder:b17,leftstick:b21,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b22,righttrigger:a2,rightx:a3,righty:a4,start:b16,x:b13,y:b14,platform:Linux, 030000005f140000c501000010010000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux, 03000000100800000100000010010000,Twin PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, 03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux, 03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux, 03000000790000001100000000010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux, 030000006f0e00000302000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 030000006f0e00000702000011010000,Victrix Pro Fightstick PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux, 05000000ac0500003232000001000000,VR Box Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux, 05000000434f4d4d414e440000000000,VX Gaming Command Series,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 0000000058626f782033363020576900,Xbox 360 Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux, 030000005e0400001907000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000014010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400009102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000a102000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000a102000007010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400008e02000000010000,Xbox 360 EasySMX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000a102000014010000,Xbox 360 Receiver,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400000202000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, 030000006f0e00001304000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000ffff0000ffff000000010000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux, 0000000058626f782047616d65706100,Xbox Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux, 030000005e0400000a0b000005040000,Xbox One Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux, 030000005e040000120b000009050000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000d102000002010000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000ea02000001030000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000005e040000e002000003090000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000005e040000fd02000003090000,Xbox One Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000fd02000030110000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 060000005e040000120b000007050000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000005e040000e302000002090000,Xbox One Elite,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000220b000013050000,Xbox One Elite 2 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 060000005e040000ea0200000b050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 060000005e040000ea0200000d050000,Xbox One S Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000120b000001050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000120b000005050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000120b00000d050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000130b000001050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000130b000005050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000130b000009050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000130b000013050000,Xbox Series Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 060000005e040000120b00000b050000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 030000005e040000120b000007050000,Xbox Series X Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 050000005e040000130b000011050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000130b000007050000,Xbox Series X Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 050000005e040000200b000013050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux, 03000000450c00002043000010010000,XEOX SL6556 BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux, 05000000172700004431000029010000,XiaoMi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Linux, 03000000c0160000e105000001010000,XinMo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux, xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux, 03000000120c0000100e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux, 03000000120c0000101e000011010000,Zeroplus P4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,AntiMicroX-antimicrox-b300273/share/gamecontrollerdb_windows.txt000066400000000000000000006014151471077622000251210ustar00rootroot00000000000000# Game Controller DB for SDL in 2.0.16 format # Source: https://github.com/gabomdq/SDL_GameControllerDB # Windows 03000000300f00000a01000000000000,3 In 1 Conversion Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows, 03000000fa2d00000100000000000000,3dRudder Foot Motion Controller,leftx:a0,lefty:a1,rightx:a5,righty:a2,platform:Windows, 03000000d0160000040d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows, 03000000d0160000050d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows, 03000000d0160000060d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows, 03000000d0160000070d000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows, 03000000d0160000600a000000000000,4Play Adapter,a:b1,b:b3,back:b4,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,leftstick:b14,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b15,righttrigger:b9,rightx:a3,righty:a4,start:b5,x:b0,y:b2,platform:Windows, 03000000c82d00000031000000000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000531000000000000,8BitDo Adapter 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000951000000000000,8BitDo Dogbone,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightx:a3,righty:a5,start:b11,platform:Windows, 03000000008000000210000000000000,8BitDo F30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 030000003512000011ab000000000000,8BitDo F30 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000c82d00001028000000000000,8BitDo F30 Arcade Joystick,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d000011ab000000000000,8BitDo F30 Arcade Joystick,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000801000000900000000000000,8BitDo F30 Arcade Stick,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00001038000000000000,8BitDo F30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001251000000000000,8BitDo Lite 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001151000000000000,8BitDo Lite SE,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000150000000000000,8BitDo M30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000151000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000650000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00005106000000000000,8BitDo M30,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,guide:b2,leftshoulder:b8,lefttrigger:b9,rightshoulder:b6,righttrigger:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000310000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000451000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a2,rightx:a3,righty:a5,start:b11,platform:Windows, 03000000c82d00002028000000000000,8BitDo N30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00008010000000000000,8BitDo N30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d0000e002000000000000,8BitDo N30,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b6,platform:Windows, 03000000c82d00000190000000000000,8BitDo N30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000290000000000000,8BitDo N64,+rightx:b9,+righty:b3,-rightx:b4,-righty:b8,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,platform:Windows, 03000000c82d00003038000000000000,8BitDo N64,+rightx:b9,+righty:b3,-rightx:b4,-righty:b8,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,platform:Windows, 030000003512000012ab000000000000,8BitDo NES30,a:b2,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b0,platform:Windows, 03000000c82d000012ab000000000000,8BitDo NES30,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000022000000090000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000203800000900000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00002038000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000751000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000851000000000000,8BitDo P30,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000360000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000361000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000660000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000131000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000231000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000331000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000431000000000000,8BitDo Receiver,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00002867000000000000,8BitDo S30,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,lefttrigger:b9,leftx:a0,lefty:a2,rightshoulder:b6,righttrigger:b7,rightx:a3,righty:a5,start:b10,x:b3,y:b4,platform:Windows, 03000000c82d00000130000000000000,8BitDo SF30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000060000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000061000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000102800000900000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d000021ab000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00003028000000000000,8BitDo SFC30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 030000003512000020ab000000000000,8BitDo SN30,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000030000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000351000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a2,rightshoulder:b7,rightx:a3,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001290000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d000020ab000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00004028000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00006228000000000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000021000000000000,8BitDo SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000161000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000121000000000000,8BitDo SN30 Pro for Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00001330000000000000,8BitDo Ultimate Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000a00500003232000000000000,8BitDo Zero,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Windows, 03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows, 03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Windows, 030000008f0e00001200000000000000,Acme GA02,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows, 03000000c01100000355000000000000,Acrux,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000fa190000f0ff000000000000,Acteck AGJ 3200,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000d1180000402c000000000000,ADT1,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a3,rightx:a2,righty:a5,x:b3,y:b4,platform:Windows, 03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00000263000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00001101000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00001401000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00001402000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00001901000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00001a01000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00001301000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006f0e00001302000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006f0e00001304000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006f0e00001413000000000000,Afterglow Xbox Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00003901000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000ab1200000103000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000ad1b000000f9000000000000,Afterglow Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000100000008200000000000000,Akishop Customs PS360,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000007c1800000006000000000000,Alienware Dual Compatible PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 03000000491900001904000000000000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows, 03000000710100001904000000000000,Amazon Luna Controller,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b8,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b4,rightstick:b7,rightx:a3,righty:a4,start:b6,x:b3,y:b2,platform:Windows, 03000000830500000160000000000000,Arcade,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b4,platform:Windows, 03000000120c0000100e000000000000,Armor 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000490b00004406000000000000,ASCII Seamic Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows, 03000000869800002500000000000000,Astro C40 TR PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000a30c00002700000000000000,Astro City Mini,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows, 03000000a30c00002800000000000000,Astro City Mini,a:b2,b:b1,back:b8,leftx:a3,lefty:a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows, 03000000050b00000579000000000000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000050b00000679000000000000,ASUS ROG Kunai 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000e4150000103f000000000000,Batarang,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000d6200000e557000000000000,Batarang PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows, 030000006f0e00003201000000000000,Battlefield 4 PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000ad1b000001f9000000000000,BB 070,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000d62000002a79000000000000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000bc2000005250000000000000,Beitong G3,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:b9,rightx:a3,righty:a4,start:b15,x:b3,y:b4,platform:Windows, 030000000d0500000208000000000000,Belkin Nostromo N40,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows, 03000000bc2000006012000000000000,Betop 2126F,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000bc2000000055000000000000,Betop BFM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000bc2000006312000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000bc2000006321000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000bc2000006412000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000c01100000555000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000c01100000655000000000000,Betop Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000790000000700000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 03000000808300000300000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 030000006f0e00006401000000000000,BF One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows, 03000000300f00000202000000000000,Bigben,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a5,righty:a2,start:b7,x:b2,y:b3,platform:Windows, 030000006b1400000209000000000000,Bigben,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006b1400000055000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000006b1400000103000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, 03000000120c0000200e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000210e000000000000,Brook Mars PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000f10e000000000000,Brook PS2 Adapter,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000310c000000000000,Brook Super Converter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows, 03000000d81d00000b00000000000000,Buffalo BSGP1601 Series,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows, 030000005b1c00002400000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows, 030000005b1c00002500000000000000,Capcom Home Arcade Controller,a:b3,b:b4,back:b7,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b6,x:b0,y:b1,platform:Windows, 030000006d04000042c2000000000000,ChillStream,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000457500000401000000000000,Cobra,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000b0400003365000000000000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Windows, 030000004c050000c505000000000000,CronusMax Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000d814000007cd000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000d8140000cefa000000000000,Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Windows, 030000003807000002cb000000000000,Cyborg,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000a306000022f6000000000000,Cyborg V.3 Rumble,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000f806000000a3000000000000,DA Leader,a:b7,b:b6,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b0,leftstick:b8,lefttrigger:b1,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:b3,rightx:a2,righty:a3,start:b12,x:b4,y:b5,platform:Windows, 030000001a1c00000001000000000000,Datel Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000451300000830000000000000,Defender Game Racer X7,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000791d00000103000000000000,Dual Box Wii,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000c0160000e105000000000000,Dual Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 030000004f040000070f000000000000,Dual Power,a:b8,b:b9,back:b4,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,leftshoulder:b13,leftstick:b6,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b12,rightstick:b7,righttrigger:b15,start:b5,x:b10,y:b11,platform:Windows, 030000004f04000012b3000000000000,Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, 030000004f04000020b3000000000000,Dual Trigger,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, 03000000bd12000002e0000000000000,Dual Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows, 03000000ff1100003133000000000000,DualForce,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b1,platform:Windows, 030000008f0e00000910000000000000,DualShock 2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,platform:Windows, 03000000317300000100000000000000,DualShock 3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 030000006f0e00003001000000000000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000fc0400000250000000000000,Easy Grip,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows, 030000006e0500000a20000000000000,Elecom DUX60 MMO,a:b2,b:b3,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b14,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b15,righttrigger:b13,rightx:a3,righty:a4,start:b20,x:b0,y:b1,platform:Windows, 03000000b80500000410000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows, 03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows, 030000006e0500000520000000000000,Elecom P301U PlayStation Controller Adapter,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows, 03000000411200004450000000000000,Elecom U1012,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows, 030000006e0500000320000000000000,Elecom U3613M,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows, 030000006e0500000e20000000000000,Elecom U3912T,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows, 030000006e0500000f20000000000000,Elecom U4013S,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Windows, 030000006e0500001320000000000000,Elecom U4113,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006e0500001020000000000000,Elecom U4113S,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows, 030000006e0500000720000000000000,Elecom W01U,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows, 030000007d0400000640000000000000,Eliminator AfterShock,a:b1,b:b2,back:b9,dpdown:+a3,dpleft:-a5,dpright:+a5,dpup:-a3,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a4,righty:a2,start:b8,x:b0,y:b3,platform:Windows, 03000000120c0000f61c000000000000,Elite,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000430b00000300000000000000,EMS Production PS2 Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 03000000242f000000b7000000000000,ESM 9110,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Windows, 03000000101c0000181c000000000000,Essential,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b4,leftx:a1,lefty:a0,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 030000008f0e00000f31000000000000,EXEQ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, 03000000341a00000108000000000000,EXEQ RF Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000006f0e00008401000000000000,Faceoff Deluxe Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00008001000000000000,Faceoff Pro Nintendo Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000021000000090000000000000,FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b4,y:b3,platform:Windows, 0300000011040000c600000000000000,FC801,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows, 03000000852100000201000000000000,FF GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000ad1b000028f0000000000000,Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000ad1b00002ef0000000000000,Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000ad1b000038f0000000000000,Fightpad TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows, 03000000f806000001a3000000000000,Firestorm,a:b9,b:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b0,leftstick:b10,lefttrigger:b1,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,start:b12,x:b8,y:b4,platform:Windows, 03000000b50700000399000000000000,Firestorm 2,a:b2,b:b4,back:b10,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b9,start:b11,x:b3,y:b5,platform:Windows, 03000000b50700001302000000000000,Firestorm D3,a:b0,b:b2,leftshoulder:b4,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,x:b1,y:b3,platform:Windows, 03000000b40400001024000000000000,Flydigi Apex,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000151900004000000000000000,Flydigi Vader 2,a:b11,b:b10,back:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,leftstick:b1,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b0,righttrigger:b4,rightx:a3,righty:a4,start:b2,x:b9,y:b8,platform:Windows, 03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b4,paddle2:b5,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,platform:Windows, 03000000b40400001224000000000000,Flydigi Vader 2 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,paddle3:b17,paddle4:b18,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows, 030000008305000000a0000000000000,G08XU,a:b0,b:b1,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b5,x:b2,y:b3,platform:Windows, 0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows, 03000000260900002625000000000000,GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows, 03000000341a000005f7000000000000,GameCube Controller,a:b2,b:b3,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b1,y:b0,platform:Windows, 03000000430b00000500000000000000,GameCube Controller,a:b0,b:b2,dpdown:b10,dpleft:b8,dpright:b9,dpup:b11,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a3,rightx:a5,righty:a2,start:b7,x:b1,y:b3,platform:Windows, 03000000790000004718000000000000,GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows, 03000000790000004618000000000000,GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows, 030000008f0e00000d31000000000000,Gamepad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000ac0500003d03000000000000,GameSir G3,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000ac0500005b05000000000000,GameSir G3w,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000ac0500002d02000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000ac0500004d04000000000000,GameSir G4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 030000004c0e00001035000000000000,Gamester,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 030000000d0f00001110000000000000,GameStick Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 0300000047530000616d000000000000,GameStop,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000c01100000140000000000000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000b62500000100000000000000,Gametel GT004 01,a:b3,b:b0,dpdown:b10,dpleft:b9,dpright:b8,dpup:b11,leftshoulder:b4,rightshoulder:b5,start:b7,x:b1,y:b2,platform:Windows, 030000008f0e00001411000000000000,Gamo2 Divaller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000a857000000000000,Gator Claw,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000c9110000f055000000000000,GC100XF,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000008305000009a0000000000000,Genius,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000008305000031b0000000000000,Genius Maxfire Blaze 3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000451300000010000000000000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000005c1a00003330000000000000,Genius MaxFire Grandias 12V,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows, 03000000300f00000b01000000000000,GGE909 Recoil,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 03000000f0250000c283000000000000,Gioteck PlayStation Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000f025000021c1000000000000,Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000f025000031c1000000000000,Gioteck PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000f0250000c383000000000000,Gioteck VX2 PlayStation Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000f0250000c483000000000000,Gioteck VX2 PlayStation Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 030000004f04000026b3000000000000,GP XID,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 0300000079000000d418000000000000,GPD Win,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000c6240000025b000000000000,GPX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000007d0400000840000000000000,Gravis Destroyer Tilt,+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,x:b0,y:b3,platform:Windows, 030000007d0400000540000000000000,Gravis Eliminator Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 03000000280400000140000000000000,Gravis GamePad Pro,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a3,dpup:-a4,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000008f0e00000610000000000000,GreenAsia,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a5,righty:a2,start:b11,x:b3,y:b0,platform:Windows, 03000000ac0500006b05000000000000,GT2a,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00004900000000000000,Hatsune Miku Sho PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000001008000001e1000000000000,Havit HV G60,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows, 030000000d0f00000c00000000000000,HEXT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000d81400000862000000000000,HitBox Edition Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, 03000000632500002605000000000000,HJD X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 030000000d0f00000a00000000000000,Hori DOA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000000d0f00008500000000000000,Hori Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00002500000000000000,Hori Fighting Commander 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00002d00000000000000,Hori Fighting Commander 3 Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00005f00000000000000,Hori Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00005e00000000000000,Hori Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00008400000000000000,Hori Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00005100000000000000,Hori Fighting Commander PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00008600000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000000d0f0000ba00000000000000,Hori Fighting Commander Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000000d0f00008800000000000000,Hori Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, 030000000d0f00008700000000000000,Hori Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00001000000000000000,Hori Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00003200000000000000,Hori Fightstick 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000c000000000000000,Hori Fightstick 4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000000d0f00000d00000000000000,Hori Fightstick EX2,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 030000000d0f00003701000000000000,Hori Fightstick Mini,a:b1,b:b0,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b3,y:b2,platform:Windows, 030000000d0f00004000000000000000,Hori Fightstick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00002100000000000000,Hori Fightstick V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00002700000000000000,Hori Fightstick V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000a000000000000000,Hori Grip TAC4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b13,x:b0,y:b3,platform:Windows, 030000000d0f0000a500000000000000,Hori Miku Project Diva X HD PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000a600000000000000,Hori Miku Project Diva X HD PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00000101000000000000,Hori Mini Hatsune Miku FT,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00005400000000000000,Hori Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00000900000000000000,Hori Pad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00004d00000000000000,Hori Pad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00003801000000000000,Hori PC Engine Mini Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,platform:Windows, 030000000d0f00009200000000000000,Hori Pokken Tournament DX Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00002301000000000000,Hori PS4 Controller Light,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 030000000d0f00001100000000000000,Hori Real Arcade Pro 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00002600000000000000,Hori Real Arcade Pro 3P,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00004b00000000000000,Hori Real Arcade Pro 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00006a00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00006b00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00008a00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00008b00000000000000,Hori Real Arcade Pro 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00006f00000000000000,Hori Real Arcade Pro 4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00007000000000000000,Hori Real Arcade Pro 4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00003d00000000000000,Hori Real Arcade Pro N3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b10,leftstick:b4,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b6,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000ae00000000000000,Hori Real Arcade Pro N4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000000d0f00008c00000000000000,Hori Real Arcade Pro P4,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000000d0f0000aa00000000000000,Hori Real Arcade Pro S,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000d800000000000000,Hori Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Windows, 030000000d0f00002200000000000000,Hori Real Arcade Pro V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00005b00000000000000,Hori Real Arcade Pro V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00005c00000000000000,Hori Real Arcade Pro V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000af00000000000000,Hori Real Arcade Pro VHS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00001b00000000000000,Hori Real Arcade Pro VX,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000ad1b000002f5000000000000,Hori Real Arcade Pro VX,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Windows, 030000000d0f00009c00000000000000,Hori TAC Pro,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000c900000000000000,Hori Taiko Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000c100000000000000,Horipad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00006400000000000000,Horipad 3TP,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00001300000000000000,Horipad 3W,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00005500000000000000,Horipad 4 FPS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00006e00000000000000,Horipad 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00006600000000000000,Horipad 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00004200000000000000,Horipad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000ad1b000001f5000000000000,Horipad EXT2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000000d0f0000ee00000000000000,Horipad Mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f00006700000000000000,Horipad One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000000d0f0000dc00000000000000,Horipad Switch,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,platform:Windows, 03000000790000004e95000000000000,Hyperkin N64 Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b7,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a5,righty:a2,start:b9,platform:Windows, 03000000d81d00000e00000000000000,iBuffalo AC02 Arcade Joystick,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b11,righttrigger:b3,rightx:a2,righty:a5,start:b8,x:b4,y:b5,platform:Windows, 03000000d81d00000f00000000000000,iBuffalo BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000d81d00001000000000000000,iBuffalo BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 030000005c0a00000285000000000000,iDroidCon,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b6,platform:Windows, 03000000696400006964000000000000,iDroidCon Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000b50700001403000000000000,Impact Black,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, 030000006f0e00002401000000000000,Injustice Fightstick PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 03000000830500005130000000000000,InterAct ActionPad,a:b0,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows, 03000000ef0500000300000000000000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,platform:Windows, 03000000fd0500000230000000000000,InterAct AxisPad,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows, 03000000fd0500000030000000000000,Interact GoPad,a:b3,b:b4,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows, 03000000fd0500003902000000000000,InterAct Hammerhead,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b2,lefttrigger:b8,rightshoulder:b7,rightstick:b5,righttrigger:b9,start:b10,x:b0,y:b1,platform:Windows, 03000000fd0500002a26000000000000,InterAct Hammerhead FX,a:b3,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b0,y:b1,platform:Windows, 03000000fd0500002f26000000000000,InterAct Hammerhead FX,a:b4,b:b5,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b1,y:b2,platform:Windows, 03000000fd0500005302000000000000,InterAct ProPad,a:b3,b:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,x:b0,y:b1,platform:Windows, 03000000ac0500002c02000000000000,Ipega Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000491900000204000000000000,Ipega PG9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000491900000304000000000000,Ipega PG9087,+righty:+a5,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows, 030000007e0500000620000000000000,Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b13,leftshoulder:b4,leftstick:b10,rightshoulder:b5,start:b8,x:b2,y:b3,platform:Windows, 030000007e0500000720000000000000,Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b1,back:b12,leftshoulder:b4,leftstick:b11,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, 03000000250900000017000000000000,Joypad Adapter,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows, 03000000bd12000003c0000000000000,Joypad Alpha Shock,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000ff1100004033000000000000,JPD FFB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a2,start:b15,x:b3,y:b0,platform:Windows, 03000000242f00002d00000000000000,JYS Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000242f00008a00000000000000,JYS Adapter,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, 03000000c4100000c082000000000000,KADE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000828200000180000000000000,Keio,a:b4,b:b5,back:b8,leftshoulder:b2,lefttrigger:b3,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b9,x:b0,y:b1,platform:Windows, 03000000790000000200000000000000,King PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 03000000bd12000001e0000000000000,Leadership,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 030000006f0e00000103000000000000,Logic3,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006f0e00000104000000000000,Logic3,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000008f0e00001300000000000000,Logic3,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 030000006d040000d1ca000000000000,Logitech ChillStream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d040000d2ca000000000000,Logitech Cordless Precision,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows, 030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d0400001dc2000000000000,Logitech F310,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006d04000018c2000000000000,Logitech F510,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d0400001ec2000000000000,Logitech F510,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006d04000019c2000000000000,Logitech F710,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d0400001fc2000000000000,Logitech F710,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006d0400001ac2000000000000,Logitech Precision,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000006d04000009c2000000000000,Logitech WingMan,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows, 030000006d0400000bc2000000000000,Logitech WingMan Action Pad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:a5~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b5,righttrigger:a2~,start:b8,x:b3,y:b4,platform:Windows, 030000006d0400000ac2000000000000,Logitech WingMan RumblePad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows, 03000000380700005645000000000000,Lynx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000222200006000000000000000,Macally,a:b1,b:b2,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000380700003888000000000000,Mad Catz Arcade Fightstick TE S Plus PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000380700008532000000000000,Mad Catz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000380700006352000000000000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000380700006652000000000000,Mad Catz CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000380700005032000000000000,Mad Catz Fightpad Pro PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000380700005082000000000000,Mad Catz Fightpad Pro PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000380700008031000000000000,Mad Catz FightStick Alpha PS3 ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000003807000038b7000000000000,Mad Catz Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows, 03000000380700008433000000000000,Mad Catz Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000380700008483000000000000,Mad Catz Fightstick TE S PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000380700008134000000000000,Mad Catz Fightstick TE2 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000380700008184000000000000,Mad Catz Fightstick TE2 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000380700006252000000000000,Mad Catz Micro CTRLR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000380700008232000000000000,Mad Catz PlayStation Brawlpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000380700008731000000000000,Mad Catz PlayStation Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000003807000056a8000000000000,Mad Catz PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000380700001888000000000000,Mad Catz SFIV Fightstick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000380700008081000000000000,Mad Catz SFV Arcade Fightstick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000380700001847000000000000,Mad Catz Street Fighter 4 Xbox 360 FightStick,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows, 03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000002a0600001024000000000000,Matricom,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows, 030000009f000000adbb000000000000,MaxJoypad Virtual Controller,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows, 03000000242f00003700000000000000,Mayflash F101,a:b1,b:b2,back:b8,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 03000000790000003018000000000000,Mayflash F300 Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 03000000242f00003900000000000000,Mayflash F300 Elite Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 03000000242f00007300000000000000,Mayflash Magic NS,a:b1,b:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, 0300000079000000d218000000000000,Mayflash Magic NS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000d620000010a7000000000000,Mayflash Magic NS,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000008f0e00001030000000000000,Mayflash Sega Saturn Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows, 0300000025090000e803000000000000,Mayflash Wii Classic Adapter,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, 03000000790000000318000000000000,Mayflash Wii DolphinBar,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,platform:Windows, 03000000790000000018000000000000,Mayflash Wii U Pro Adapter,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000790000002418000000000000,Mega Drive Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,rightshoulder:b2,start:b9,x:b3,y:b4,platform:Windows, 0300000079000000ae18000000000000,Mega Drive Controller,a:b0,b:b1,back:b7,dpdown:b14,dpleft:b15,dpright:b13,dpup:b2,rightshoulder:b6,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows, 03000000c0160000990a000000000000,Mega Drive Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,righttrigger:b2,start:b3,platform:Windows, 030000005e0400002800000000000000,Microsoft Dual Strike,a:b3,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,rightx:a0,righty:a1~,start:b5,x:b1,y:b0,platform:Windows, 030000005e0400000300000000000000,Microsoft SideWinder,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows, 030000005e0400000700000000000000,Microsoft SideWinder,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows, 030000005e0400000e00000000000000,Microsoft SideWinder Freestyle Pro,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b8,x:b3,y:b4,platform:Windows, 030000005e0400002700000000000000,Microsoft SideWinder Plug and Play,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b4,righttrigger:b5,x:b2,y:b3,platform:Windows, 03000000280d00000202000000000000,Miller Lite Cantroller,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b5,x:b2,y:b3,platform:Windows, 03000000ad1b000023f0000000000000,MLG,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a6,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 03000000ad1b00003ef0000000000000,MLG Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows, 03000000380700006382000000000000,MLG PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000ffff00000000000000000000,Mocute M053,a:b3,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b11,leftstick:b7,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b6,righttrigger:b4,rightx:a3,righty:a4,start:b8,x:b1,y:b0,platform:Windows, 03000000d6200000e589000000000000,Moga 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows, 03000000d62000007162000000000000,Moga Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a2,righty:a5,start:b7,x:b2,y:b3,platform:Windows, 03000000d6200000ad0d000000000000,Moga Pro,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000c62400002a89000000000000,Moga XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c62400002b89000000000000,Moga XP5A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c62400001a89000000000000,Moga XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c62400001b89000000000000,Moga XP5X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000efbe0000edfe000000000000,Monect Virtual Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 03000000091200004488000000000000,MUSIA PlayStation 2 Input Display,a:b0,b:b2,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b6,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:b11,rightx:a2,righty:a3,start:b5,x:b1,y:b3,platform:Windows, 03000000f70600000100000000000000,N64 Adaptoid,+rightx:b2,+righty:b1,-rightx:b4,-righty:b5,a:b0,b:b3,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,platform:Windows, 030000006b140000010c000000000000,Nacon GC 400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000006b1400001106000000000000,Nacon Revolution 3 PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000006b140000100d000000000000,Nacon Revolution Infinity PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006b140000080d000000000000,Nacon Revolution Unlimited Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000bd12000001c0000000000000,Nebular,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 03000000eb0300000000000000000000,NeGcon Adapter,a:a2,b:b13,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,lefttrigger:a4,leftx:a1,righttrigger:b11,start:b3,x:a3,y:b12,platform:Windows, 0300000038070000efbe000000000000,NEO SE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 0300000092120000474e000000000000,NeoGeo X Arcade Stick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b9,x:b3,y:b2,platform:Windows, 03000000921200004b46000000000000,NES 2 port Adapter,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,start:b11,platform:Windows, 03000000000f00000100000000000000,NES Controller,a:b1,b:b0,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows, 03000000921200004346000000000000,NES Controller,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows, 03000000790000004518000000000000,NEXILUX GameCube Controller Adapter,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows, 030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,righttrigger:b6,start:b9,x:b3,y:b0,platform:Windows, 03000000050b00000045000000000000,Nexus,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,platform:Windows, 03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000000d0500000308000000000000,Nostromo N45,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Windows, 030000007e0500001920000000000000,NSO N64 Controller,+rightx:b8,+righty:b2,-rightx:b3,-righty:b7,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,righttrigger:b10,start:b9,platform:Windows, 030000007e0500001720000000000000,NSO SNES Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b15,start:b9,x:b2,y:b3,platform:Windows, 03000000550900001472000000000000,NVIDIA Controller,a:b11,b:b10,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b5,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b4,righttrigger:a5,rightx:a3,righty:a6,start:b3,x:b9,y:b8,platform:Windows, 03000000550900001072000000000000,NVIDIA Shield,a:b9,b:b8,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b3,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b2,righttrigger:a4,rightx:a2,righty:a5,start:b0,x:b7,y:b6,platform:Windows, 030000005509000000b4000000000000,NVIDIA Virtual,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000120c00000288000000000000,Nyko Air Flo Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 030000004b120000014d000000000000,Nyko Airflo,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows, 03000000d62000001d57000000000000,Nyko Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000791d00000900000000000000,Nyko Playpad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000782300000a10000000000000,Onlive Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,platform:Windows, 030000000d0f00000401000000000000,Onyx,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000008916000001fd000000000000,Onza CE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a3,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000008916000000fd000000000000,Onza TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,platform:Windows, 03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,platform:Windows, 03000000120c0000f60e000000000000,P4 Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows, 03000000790000002201000000000000,PC Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 030000006f0e00008501000000000000,PDP Fightpad Pro,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b0,platform:Windows, 030000006f0e00000901000000000000,PDP Versus Fighting,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000008f0e00004100000000000000,PlaySega,a:b1,b:b0,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b4,y:b3,platform:Windows, 03000000e30500009605000000000000,PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 030000004c050000da0c000000000000,PlayStation Classic Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows, 03000000632500002306000000000000,PlayStation Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows, 03000000f0250000c183000000000000,PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000d9040000160f000000000000,PlayStation Controller Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 030000004c0500003713000000000000,PlayStation Vita,a:b1,b:b2,back:b8,dpdown:b13,dpleft:b15,dpright:b14,dpup:b12,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 0300000062060000d570000000000000,PowerA PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000d620000013a7000000000000,PowerA Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d04000084ca000000000000,Precision,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 03000000d62000009557000000000000,Pro Elite PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000c62400001a53000000000000,Pro Ex Mini,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000d62000009f31000000000000,Pro Ex mini PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000d6200000c757000000000000,Pro Ex mini PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000110e000000000000,Pro5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000100800000100000000000000,PS1 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 030000008f0e00007530000000000000,PS1 Controller,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b1,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000100800000300000000000000,PS2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 03000000250900000088000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 03000000250900006888000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b6,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 03000000250900008888000000000000,PS2 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 03000000666600006706000000000000,PlayStation Adapter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Windows, 030000006b1400000303000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000009d0d00001330000000000000,PS2 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000151a00006222000000000000,PS2 Dual Plus Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 03000000120a00000100000000000000,PS3 Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000120c00001307000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c00001cf1000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000f90e000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000250900000118000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 03000000250900000218000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 03000000250900000500000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows, 030000004c0500006802000000000000,PS3 Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b10,lefttrigger:a3~,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:a4~,rightx:a2,righty:a5,start:b8,x:b3,y:b0,platform:Windows, 030000004f1f00000800000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 03000000632500007505000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000888800000803000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows, 03000000888800000804000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,leftshoulder:b10,leftstick:b1,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows, 030000008f0e00000300000000000000,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows, 030000008f0e00001431000000000000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000ba2200002010000000000000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b3,y:b2,platform:Windows, 03000000120c00000807000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000111e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000121e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000130e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000150e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000180e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000181e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000191e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c00001e0e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000a957000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000aa57000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000f21c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000f31c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000f41c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000f51c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120c0000f70e000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000120e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000160e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000001a1e0000120c000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows, 030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows, 03000000830500005020000000000000,PSX,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b2,y:b3,platform:Windows, 03000000300f00000111000000000000,Qanba 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00000211000000000000,Qanba 2P,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000300f00000011000000000000,Qanba Arcade Stick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows, 03000000300f00001611000000000000,Qanba Arcade Stick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows, 03000000222c00000025000000000000,Qanba Dragon Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000222c00000020000000000000,Qanba Drone Arcade Stick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00001211000000000000,Qanba Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00001210000000000000,Qanba Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows, 03000000341a00000104000000000000,Qanba Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows, 03000000222c00000223000000000000,Qanba Obsidian Arcade Stick PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000222c00000023000000000000,Qanba Obsidian Arcade Stick PS4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000008a2400006682000000000000,R1 Mobile Controller,a:b3,b:b1,back:b7,leftx:a0,lefty:a1,start:b6,x:b4,y:b0,platform:Windows, 03000000086700006626000000000000,RadioShack,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows, 03000000ff1100004733000000000000,Ramox FPS Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b0,platform:Windows, 030000009b2800002300000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows, 030000009b2800006900000000000000,Raphnet 3DO Adapter,a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b2,start:b3,platform:Windows, 030000009b2800000800000000000000,Raphnet Dreamcast Adapter,a:b2,b:b1,dpdown:b5,dpleft:b6,dpright:b7,dpup:b4,lefttrigger:a2,leftx:a0,righttrigger:a3,righty:a1,start:b3,x:b10,y:b9,platform:Windows, 030000009b2800003200000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows, 030000009b2800006000000000000000,Raphnet GC and N64 Adapter,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,righty:a4,start:b3,x:b1,y:b8,platform:Windows, 030000009b2800001800000000000000,Raphnet Jaguar Adapter,a:b2,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b0,righttrigger:b10,start:b3,x:b11,y:b12,platform:Windows, 030000009b2800000200000000000000,Raphnet NES Adapter,a:b7,b:b6,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,start:b4,platform:Windows, 030000009b2800004400000000000000,Raphnet PS1 and PS2 Adapter,a:b1,b:b2,back:b5,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b9,rightx:a3,righty:a4,start:b4,x:b0,y:b3,platform:Windows, 030000009b2800004300000000000000,Raphnet Saturn,a:b0,b:b1,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows, 030000009b2800000500000000000000,Raphnet Saturn Adapter 2.0,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, 030000009b2800000300000000000000,Raphnet SNES Adapter,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows, 030000009b2800005600000000000000,Raphnet SNES Adapter,a:b1,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows, 030000009b2800005700000000000000,Raphnet SNES Adapter,a:b1,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,platform:Windows, 030000009b2800001e00000000000000,Raphnet Vectrex Adapter,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a1,lefty:a2,x:b2,y:b3,platform:Windows, 030000009b2800002b00000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows, 030000009b2800002c00000000000000,Raphnet Wii Classic Adapter,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b3,x:b0,y:b5,platform:Windows, 03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000321500000204000000000000,Razer Panthera PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000104000000000000,Razer Panthera PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000010000000000000,Razer Raiju,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000507000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000321500000707000000000000,Razer Raiju Mobile,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000321500000710000000000000,Razer Raiju TE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000a10000000000000,Razer Raiju TE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000410000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000910000000000000,Razer Raiju UE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000011000000000000,Razer Raion PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000321500000009000000000000,Razer Serval,+lefty:+a2,-lefty:-a1,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,leftx:a0,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000921200004547000000000000,Retro Bit Sega Genesis Controller Adapter,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b6,x:b3,y:b4,platform:Windows, 03000000790000001100000000000000,Retro Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, 03000000830500006020000000000000,Retro Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b8,righttrigger:b9,start:b7,x:b2,y:b3,platform:Windows, 03000000bd12000013d0000000000000,Retrolink Sega Saturn Classic Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b5,lefttrigger:b6,rightshoulder:b2,righttrigger:b7,start:b8,x:b3,y:b4,platform:Windows, 03000000bd12000015d0000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows, 0300000000f000000300000000000000,RetroUSB RetroPad,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, 0300000000f00000f100000000000000,RetroUSB Super RetroPort,a:b1,b:b5,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows, 03000000830500000960000000000000,Revenger,a:b0,b:b1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b3,x:b4,y:b5,platform:Windows, 030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000006b140000020d000000000000,Revolution Pro Controller 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000006b140000130d000000000000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00001f01000000000000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006f0e00004601000000000000,Rock Candy,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000c6240000fefa000000000000,Rock Candy Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006f0e00001e01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00002801000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00002f01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00008701000000000000,Rock Candy Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows, 03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows, 03000000050b00005819000000000000,ROG Chakram Core,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows, 03000000050b0000181a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows, 03000000050b00001a1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows, 03000000050b00001c1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,platform:Windows, 030000004f04000001d0000000000000,Rumble Force,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, 030000008916000000fe000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000c6240000045d000000000000,Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000a306000023f6000000000000,Saitek Cyborg V.1 Game,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00001201000000000000,Saitek Dual Analog,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, 03000000a30600000701000000000000,Saitek P220,a:b2,b:b3,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b4,righttrigger:b5,x:b0,y:b1,platform:Windows, 03000000a30600000cff000000000000,Saitek P2500 Force Rumble,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b0,y:b1,platform:Windows, 03000000a30600000d5f000000000000,Saitek P2600,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,platform:Windows, 03000000a30600000dff000000000000,Saitek P2600,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b8,x:b0,y:b3,platform:Windows, 03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 03000000a306000018f5000000000000,Saitek P3200,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00001001000000000000,Saitek P480 Rumble,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, 03000000a30600000901000000000000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b8,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b5,rightx:a3,righty:a2,x:b0,y:b1,platform:Windows, 03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows, 03000000a30600002106000000000000,Saitek PS1000 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000a306000020f6000000000000,Saitek PS2700 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows, 03000000300f00001101000000000000,Saitek Rumble,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, 03000000e804000000a0000000000000,Samsung EIGP20,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000c01100000252000000000000,Sanwa Easy Grip,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows, 03000000c01100004350000000000000,Sanwa Micro Grip P3,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,x:b3,y:b2,platform:Windows, 03000000411200004550000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a1,righty:a2,start:b9,x:b1,y:b3,platform:Windows, 03000000c01100004150000000000000,Sanwa Micro Grip Pro,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, 03000000c01100004450000000000000,Sanwa Online Grip,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b8,rightstick:b11,righttrigger:b9,rightx:a3,righty:a2,start:b14,x:b3,y:b4,platform:Windows, 03000000730700000401000000000000,Sanwa PlayOnline Mobile,a:b0,b:b1,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b3,platform:Windows, 03000000830500006120000000000000,Sanwa Smart Grip II,a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,x:b1,y:b3,platform:Windows, 03000000c01100000051000000000000,Satechi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 030000004f04000028b3000000000000,Score A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000952e00002577000000000000,Scuf PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000a30c00002500000000000000,Sega Genesis Mini 3B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,righttrigger:b5,start:b9,platform:Windows, 03000000a30c00002400000000000000,Sega Mega Drive Mini 6B Controller,a:b2,b:b1,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,rightshoulder:b4,righttrigger:b5,start:b9,x:b3,y:b0,platform:Windows, 0300000000050000289b000000000000,Sega Saturn Adapter,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows, 0300000000f000000800000000000000,Sega Saturn Controller,a:b1,b:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b7,righttrigger:b3,start:b0,x:b5,y:b6,platform:Windows, 03000000730700000601000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows, 03000000b40400000a01000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows, 030000003b07000004a1000000000000,SFX,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Windows, 03000000f82100001900000000000000,Shogun Bros Chameleon X1,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 03000000120c00001c1e000000000000,SnakeByte 4S PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 0300000003040000c197000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows, 0300000081170000960a000000000000,SNES Controller,a:b4,b:b0,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b5,y:b1,platform:Windows, 03000000811700009d0a000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows, 030000008b2800000300000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows, 03000000921200004653000000000000,SNES Controller,a:b0,b:b4,back:b2,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Windows, 03000000ff000000cb01000000000000,Sony PlayStation Portable,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000208000000000000,Speedlink 6555,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000908000000000000,Speedlink 6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000380700001722000000000000,Speedlink Competition Pro,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,x:b2,y:b3,platform:Windows, 030000008f0e00000800000000000000,Speedlink Strike FX,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000c01100000591000000000000,Speedlink Torid,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,platform:Windows, 03000000de280000fc11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000de280000ff11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000120c0000160e000000000000,Steel Play Metaltech PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000381000001214000000000000,SteelSeries Free,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Windows, 03000000110100003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000381000003014000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000381000003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,platform:Windows, 03000000790000001c18000000000000,STK 7024X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000380700003847000000000000,Street Fighter Fightstick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,start:b7,x:b2,y:b3,platform:Windows, 030000001f08000001e4000000000000,Super Famicom Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows, 03000000790000000418000000000000,Super Famicom Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b33,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows, 03000000341200001300000000000000,Super Racer,a:b2,b:b3,back:b8,leftshoulder:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b7,x:b0,y:b1,platform:Windows, 03000000d620000011a7000000000000,Switch Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000000d0f0000f600000000000000,Switch Hori Pad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000457500002211000000000000,Szmy Power PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000004f0400000ab1000000000000,T16000M,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,start:b10,x:b2,y:b3,platform:Windows, 030000000d0f00007b00000000000000,TAC GEAR,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000e40a00000207000000000000,Taito Egret II Mini Controller,a:b4,b:b2,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,guide:b9,rightshoulder:b0,righttrigger:b1,start:b7,x:b8,y:b3,platform:Windows, 03000000d814000001a0000000000000,TE Kitty,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows, 03000000ba2200000701000000000000,Technology Innovation PS2 Adapter,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b2,platform:Windows, 03000000c61100001000000000000000,Tencent Xianyou Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,x:b3,y:b4,platform:Windows, 03000000790000002601000000000000,TGZ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows, 030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, 030000004f04000023b3000000000000,Thrustmaster Dual Trigger PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000004f0400000ed0000000000000,ThrustMaster eSwap Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000004f04000008d0000000000000,ThrustMaster Ferrari 150 PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows, 030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows, 030000004f04000003d0000000000000,ThrustMaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000004f04000009d0000000000000,ThrustMaster Run N Drive PlayStation Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 030000006d04000088ca000000000000,Thunderpad,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 03000000666600000288000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 03000000666600000488000000000000,TigerGame PlayStation Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 030000004f04000007d0000000000000,TMini,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000571d00002100000000000000,Tomee NES Controller Adapter,a:b1,b:b0,back:b2,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,start:b3,platform:Windows, 03000000571d00002000000000000000,Tomee SNES Controller Adapter,a:b0,b:b1,back:b6,dpdown:+a4,dpleft:-a0,dpright:+a0,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows, 03000000d62000006000000000000000,Tournament PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000c01100000055000000000000,Tronsmart,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 030000005f140000c501000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000b80500000210000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows, 03000000411200000450000000000000,Twin Shock,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a4,start:b11,x:b3,y:b0,platform:Windows, 03000000d90400000200000000000000,TwinShock PS2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 03000000151900005678000000000000,Uniplay U6,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a3,righty:a4,start:b10,x:b3,y:b4,platform:Windows, 03000000101c0000171c000000000000,uRage Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 030000000b0400003065000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows, 03000000242f00006e00000000000000,USB Controller,a:b1,b:b4,back:b10,leftshoulder:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b7,rightx:a2,righty:a5,start:b11,x:b0,y:b3,platform:Windows, 03000000300f00000701000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 03000000341a00002308000000000000,USB Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000666600000188000000000000,USB Controller,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows, 030000006b1400000203000000000000,USB Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000790000000a00000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows, 03000000b404000081c6000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b3,y:b0,platform:Windows, 03000000b50700001503000000000000,USB Controller,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a5,righty:a2,start:b9,x:b0,y:b1,platform:Windows, 03000000bd12000012d0000000000000,USB Controller,a:b0,b:b1,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows, 03000000ff1100004133000000000000,USB Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 03000000632500002305000000000000,USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows, 03000000790000001a18000000000000,Venom,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows, 03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00000302000000000000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 030000006f0e00000702000000000000,Victrix PS4 Pro Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows, 0300000034120000adbe000000000000,vJoy Device,a:b0,b:b1,back:b15,dpdown:b6,dpleft:b7,dpright:b8,dpup:b5,guide:b16,leftshoulder:b9,leftstick:b13,lefttrigger:b11,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b14,righttrigger:b12,rightx:a3,righty:a4,start:b4,x:b2,y:b3,platform:Windows, 03000000120c0000ab57000000000000,Warrior Joypad JS083,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 030000007e0500003003000000000000,Wii U Pro,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,leftshoulder:b6,leftstick:b11,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b12,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows, 0300000032150000030a000000000000,Wildcat,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 0300000032150000140a000000000000,Wolverine,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000002e160000efbe000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,rightshoulder:b5,righttrigger:b11,start:b7,x:b2,y:b3,platform:Windows, 03000000380700001647000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000380700002045000000000000,Xbox 360 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows, 03000000380700002644000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a5,start:b8,x:b2,y:b3,platform:Windows, 03000000380700002647000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000003807000026b7000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000380700003647000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a7,righty:a5,start:b7,x:b2,y:b3,platform:Windows, 030000005e0400001907000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e0400008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e0400009102000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000ad1b000000fd000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000ad1b000001fd000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000ad1b000016f0000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000ad1b00008e02000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000c62400000053000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000c6240000fdfa000000000000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000380700002847000000000000,Xbox 360 Fightpad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000a102000000000000,Xbox 360 Wireless Receiver,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e0400000a0b000000000000,Xbox Adaptive Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000120c00000a88000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a2,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 03000000120c00001088000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2~,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5~,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000002a0600002000000000000000,Xbox Controller,a:b0,b:b1,back:b13,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,leftshoulder:b5,leftstick:b14,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b15,righttrigger:b7,rightx:a2,righty:a5,start:b12,x:b2,y:b3,platform:Windows, 03000000300f00008888000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:b13,dpleft:b10,dpright:b11,dpup:b12,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 03000000380700001645000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 03000000380700002645000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000380700003645000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 03000000380700008645000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e0400000202000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b11,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 030000005e0400008502000000000000,Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e0400008702000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b9,righttrigger:b7,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 030000005e0400008902000000000000,Xbox Controller,a:b0,b:b1,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b10,leftstick:b8,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b9,righttrigger:b4,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Windows, 030000000d0f00006300000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b9,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e0400000c0b000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000d102000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000dd02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000e002000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000e302000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000ea02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000fd02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000ff02000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006f0e0000a802000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000006f0e0000c802000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000c62400003a54000000000000,Xbox One Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000005e040000130b000000000000,Xbox Series Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 03000000450c00002043000000000000,Xeox SL6556BK,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows, 030000006f0e00000300000000000000,XGear,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a5,righty:a2,start:b9,x:b3,y:b0,platform:Windows, 03000000172700004431000000000000,Xiaomi Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,platform:Windows, 03000000172700003350000000000000,Xiaomi XMGP01YM,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000bc2000005060000000000000,Xiaomi XMGP01YM,+lefty:+a2,+righty:+a5,-lefty:-a1,-righty:-a4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,start:b11,x:b3,y:b4,platform:Windows, 03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows, 030000007d0400000340000000000000,Xterminator Digital Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:-a4,lefttrigger:+a4,leftx:a0,lefty:a1,paddle1:b7,paddle2:b6,rightshoulder:b5,rightstick:b9,righttrigger:b2,rightx:a3,righty:a5,start:b8,x:b3,y:b4,platform:Windows, 03000000790000004f18000000000000,ZDT Android Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows, 03000000120c00000500000000000000,Zeroplus Adapter,a:b2,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows, 03000000120c0000101e000000000000,Zeroplus P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,AntiMicroX-antimicrox-b300273/share/icons/000077500000000000000000000000001471077622000203675ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/000077500000000000000000000000001471077622000226725ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/128x128/000077500000000000000000000000001471077622000236275ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/128x128/apps/000077500000000000000000000000001471077622000245725ustar00rootroot00000000000000128-apps-io.github.antimicrox.antimicrox.png000066400000000000000000000132711471077622000347160ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/128x128/appsPNG  IHDR>a pHYsItEXtSoftwarewww.inkscape.org<FIDATxyUՙ޻APTpES Z:e1'L*:8ʦ&Nb8 D &(*t~^,w;s.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx#|=K2L`0_ّ*c[(q,Œ1cax P i!CjW4khȧXp Pw9h#:&Wz/N@??QfB$ +#zxGk2huO>k3, _O_UqRP@u7f4LGn,#L!%UuV>XkS*+Y4F t1p")xkw?z5:J%xʂ%W*!_N,njt(M3zɽ^_$Jb,K);>ty%F8R.J ˈN1ax=nW,xdRJu9_Y6pۈqᴚ_kBqXdR<#c Mmʵ^ݻ7ܒ pڜLQr}ME_Lme_e9 l޾ǭ"- L!5Ս< !ΣV>0iϜ:_P^;#܆0z|Rs'^B9P7(2i'Kd;L rp@pIa$6{ZpE,$ QB$g4iUY'CJ3fAʪ:'W(L͛|ݕEX1bh֫/fp]UmVr?.gC)ϝXw,Khpg1e+Py/ƌ‚YST>@eõݏO1̉:nƢ갨_:WȽY.R4LDzAFSS~$W7ڞx7/tL#x؂bUTT1 e8+Ҟ7l~ڼg@ϴL`Xar-Ӽ (x VLn|"HkGƑ c9G9Ё=p$54aL0a@s f3g&|:OGb{h?ph@WLyp`^G 0X893cѓol_tcS!-h d,/X|&DХDb&3!ײtOV40p*!4X@p0Sd'?엛D h<ߕURh )sc5{ V`ߡ1p-\atW~U vt_w|17\fm,b[Y P+ U7J7Dxm8q&nڄc&MmQB#)x+x ҡR7`O{ 2uK9c9jVXVAQ)+xl۵?uLަ~U?{ NRu4Yѓ~BJ8N{mD)H 9DG cc1B)lYnoo{0 c;[Cy ;V𡏰Fֽo޼%Iڕͫv+mfV[=iuvYkܗwX-ᯬۂOh7t̉ T8n8*q2d/c}N}xEHeFh۟|:#&*-O_ם9ԦlSޗW@Gik<7kL9lz5K;ZsԠ:KE@x|k pżp)7㈮YrSwW~'_>EqL?ޔ= ,_A,nw4S^zU=ݼYeƿ@cTy( uՕju E1\&R֝0fhyLj dDA'L,|_`E-q0[8A~;qwa;ǗAXX+ 4b-3,m^g*͟-W`-})D TC!̭!/hGwy ̸b|L1P8\m> 6n )s y1iڪZ4V?l BI!,|"9vKYqŌb]W0ȆAQ%Q~ )0{ίR4XpyD[eU yZFr&s8B)RrAw8\ߞvu;O; f;L STQg fwn蘵O6f;: (e/pGki'FCovya^̣%0%u+9S;@[(e57#0.ұ^?l*D%cKocIOgu"qc2MUWKgyDӷH3G;'a &&.[:2sv퍢q3e #:61drRwIfR1d6#0 lHXv\u9R:;}e=5>VaYHjf}uBWU{P9pL”0mq1WSO!Pi~v7a Z|zi4wJ5h*|UR:ےkSJރ=ٶ ՙfvd'-C K!)AU)舙4b8tʨX++G1b_MuLn|"( O\Tζ}Cܰ E ^ԑ lFL~fсڶr6pm,$IsGb)!AVEN|cc}-@ "!Yol-ʡᘙZ'|O_&[9#rY3ꜷZʙ^RtGGCW'Q~C!`}{Gw嗪d?e1l`tHXR!L0~_G?܀g;To0o&lj$? xO&Zkn>z_SϬI8B*j aZC`G:r^ ~bwf܎7^?'*T*^공 oRPi'~kjؤ ^-/lvE#'^H@;:#`s@[ ۡݔmݍ4,9D{}y=UolE=:Kz&T#LMnۇ4L`;ewR\-aIK^0c8. 7ys?S}dcO9 d1hq( O4.Zɻyf+lq2 Z@q?e7Auo>﫠W`Vh3_~۫|Jx3+J!4c`GV .*wd/ VӲR'^Ҩʰy] ɛtEt4u/&\p5nQo+N7΂j >ÞBbiQT9.U >!BZf}:[e_~SSZ4kS)>+*BؖU`Y@v(=BH` 6c<< |'}DZ@.KTN1K*FKOΖ‘g@ wu:u.:o(%HsQBuKpքh>׶m4]GixdCsܟ B =^Mn2 ~7bRbxH,XrA*FNhg;4ߔJx eM?+`yk|EQ?^laQ&oS(Q>C{R#$w#~Ŋs )wW$Ճv5HTiEP$HFS-˖<~7 llt4 '*HK"Qaq+,6~}"e~&+C,@4)cR(Y HXpγBx>f[B+/!.m*.x2쟏"r}/A6I|uɹwo_1qgđD f<7 וDz.@|wL$7Ypʸ+!)aK7ϛA(xiբ9Ař? #zV(?}K;W-(tn*@~R1wwpPڢn(6T 6ҷ^hc+uj@=|<.M^ CK\הl [sR[ )21zbY j+(6d7~]#V6BD"Mt m+oz]u=(֊~G7+$c[B;0e/~%arEI\]h#%{\bܥփ[I]E~{±^X:/$HT(8OMA($5U W/z'̾lFM|Q'$jʇz eכFNjT7*%O}"h)VX9~⯬^[!5˿\JXhva*ң5 2_Yyj/a.A޷NfŒ9"F_G3~bٲF8_V-{;i& h7} JoZ8| 둝 7}gF4<߱, M@uOݿ192yQ ߍB9#H`6? 3/-3f4? saʶǑR !Vkh[3!IENDB`AntiMicroX-antimicrox-b300273/share/icons/application/16x16/000077500000000000000000000000001471077622000234575ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/16x16/apps/000077500000000000000000000000001471077622000244225ustar00rootroot0000000000000016-apps-io.github.antimicrox.antimicrox.png000066400000000000000000000012401471077622000344530ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/16x16/appsPNG  IHDRasBIT|dWIDAT8ŒOQϼ@H)@T1ąA!ȎjqG• &raLX{ Nc( bKDR k:vf{.JL{s͹7DIԩc e3Ncn'Y} 7 җ/S8p+ eOwV?d;6Pr?ʹd: 6c% ӌSXBw:Qn8SyO_c)iQBg:£:6.$|Rx[ddף󳓎UH9 I߶ZRVy[tyn抹߼ sX .%%gO#7"jwZY$IENDB`AntiMicroX-antimicrox-b300273/share/icons/application/24x24/000077500000000000000000000000001471077622000234555ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/24x24/apps/000077500000000000000000000000001471077622000244205ustar00rootroot0000000000000024-apps-io.github.antimicrox.antimicrox.png000066400000000000000000000020361471077622000344540ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/24x24/appsPNG  IHDRw=sBIT|dIDATHT]OU~Μ- ||u IkQbbz1.4.ze&Djbi l;|/`7P:=>{Λ<> E'eᒊ3ۆid7n2kt3p!V<24$cЕD|~͕y7xp ߍ긹xM>+xѥMA- \w Yu9+ioqGM'8t ~[i('"Nv!3Ԝׁ7e8%.i8*] cYHe(*rB?UlY. Z!ziZN3X m࿽WpC8P0ⲠpؖSn_!VN ?b07/0,RN`ke 4 c~5) G(u|<#^M~{KХ)fW_jyL}Z[~L;Mύ 1Ƭ5`Y$ӻ 0Bڟު^,lfn~;rliiaԔ/JyB8Ik2B.kܾ# ~aIENDB`AntiMicroX-antimicrox-b300273/share/icons/application/32x32/000077500000000000000000000000001471077622000234535ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/32x32/apps/000077500000000000000000000000001471077622000244165ustar00rootroot0000000000000032-apps-io.github.antimicrox.antimicrox.png000066400000000000000000000025471471077622000344600ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/32x32/appsPNG  IHDR szzsBIT|dIDATXUKlTUιywii 4--BbcZ5&b1ƕuv7.lcЅ PB_v>yu܇i"F7vX a.t56z7Z %%A H*@Dhs\vxJf{IC%P$1STUwP;9J-g Pʀ7 >a BеKB7!]P<Ԭ)AUYQI&mL]X{;ٛ<87<![0=%u˷qt6UAHHpO Ըz/w:^<AdE-c€yd >2-2 :@4c"Rfzx;ŰǏ㾹mR: oFL1XMlJ=Ǜ}sL,Ccu9>Wv !!1%缎GꄒR3uEN/P唐8L"0>A0D QDHAhLf0,g[ꕜjb_qB7&5T1,Tm>6)kx+Rd|gէp֬褻}ݙ8ٙ_i!q_zi A ۡnw%+qp4t[ٶgXlN'" {i7o4;QS)*rh _:8s&"KG5M@UrT2ao t>,#}s '9|<8yNűiOеNSY ]Ddb_ 9\x| 6Pd)7ͪJ<UI%/]Udq~=vcm Gu[Y2<= UIƲe~xiIENDB`AntiMicroX-antimicrox-b300273/share/icons/application/48x48/000077500000000000000000000000001471077622000234715ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/48x48/apps/000077500000000000000000000000001471077622000244345ustar00rootroot0000000000000048-apps-io.github.antimicrox.antimicrox.png000066400000000000000000000044211471077622000344760ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/application/48x48/appsPNG  IHDR00WsBIT|dIDAThX[lT]?0]RA!! QJ4m($~$ԏFh~UU4QTQ"`BHlf0=w~ 6cc~yI#ͽ{}:wf1YbRhwVj}yf/-#ЈAMNM]$oS L78˂KZVѴ|+ b N" ZR3;54U),kyy?h!gK0JCM-4p_Go^dqɌ‡ Bఉy&e3&?KryaL-[h8j/Yr΃˶>{1hw <:C/&'M,m.WELfn[GvIo^ڹ /zUEp/^rPt[~rIC_'Qf4V`IC ^0)DG0P, R!xyWܪ rYAZ 18q17379)ቭ-j=p*˰41N%1h1M8D6$2ʸx!ӆ|8%>ރ_JspXAcD݂=.NaB$'n")kHf APTg.b8 Q sSOlˌwNn-yk`s,AGx:@LRxZ. ֱv,W Bΐ/$W%D*z;p{,s`sWfF/6nX= ҋ=PSE3p-.\UXY0KY>CMW~f LCIK+wZ 5Pu"̡g2&RYSӸpBe\bڿ;22T@$yc2PL`f9Ce8FnEyl/H6;8Öz|R"O=7i (|ؕ#8_o$(.;PL1Yơ['CZ ]SxhZd1^R*An óWBbX8y;lH߉~j%7l./wrEdw1^L]y5Pv^;+`xg60BD 9s p]`d#ZlA^qNHr Pu9 #5`` c 2P zu&5|uc\ڲZK s US(yS)죾` j@ 'Լp};˪׊<]I8\r7&K;FO]G^ E`|(0 6x6h߄x_mӓ݅lAοR ~X11xK&0HX,/AHius*N;>rPSևlXM, .[oݼZܯ 8&'ãi  %\䤀DHiԴJjT*E%JTh6$ )`cm1zcfvf~ci"u?̼~}~yɓ'O8gk^x4X^'!k#,k6) x&`S4QtНw'QX]<l S:tc?XQ5Y!ZDQ4e\ўv˛lǦKJ@UR9UI%][-#T Ӛ20Sʧt xO#`f,@l0$j4l) .=lsz",'㥉+ԦqMS XƄZle 4|` h-šMdW?r& DIbZUC "PlRvRo‹` #* ĠSi&*:*`w,}fx̝_.\1%A QYMN8,72e"s "Qɥn= d3{H `n;l(wrzb{SP`Niә%8i&`#2~"oO@)p@阾C |bn*fwL ZbC ֏íǂ} 3M@LQzB:`?s) "d @J4EzаMVGlZF Lq WH?8n!x fESfՒq,6,dj^ gB,hJo_kRXrW.qJURP#i AX qK %BcCVW\1sg#{*2CН|$X`/[)+pŰ.*k\#ϼxPI D:x;eX AL"vg#'XEMwxwB؛Ih癿6?,'d7N.bX^hh.|v[t|7=bV!/h-.Iuj=w?׎Q_7^FwkDBqFyxv>6rȁgw(5];*EL7z9W'*G>r=TדV=@;\?=?_=G|L!9x{?ep^Ew!;uڹc%2?Dí9-UYt~k'uco!Tהکʱ0:$c!H!of@˱Mi+x?LT96.ŏ(M0ye)8~wy`-(Uك}'b>/8ZslR{y틽Zב{u-{<ݟÅqyHکq{)*0ň cEŧ mr߷/Tע۶3-kC#'_$w_\|Nšbkrd>rl(0нFLr79Ը _pGoM'OAntiMicroX-antimicrox-b300273/share/icons/breeze_themed/000077500000000000000000000000001471077622000231715ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/share/icons/breeze_themed/48-apps-antimicrox_trayicon.png000066400000000000000000000042411471077622000311570ustar00rootroot00000000000000PNG  IHDR00WsBIT|dXIDAThY}l[W>_}yvԱ7!ͪ&ZB'C6Fb|bBh D!1 `!ZI ئ@LK`N؎yx}}unVI={~s9e`[%޵.Q/νq 5_w0v 7Wh孖&`< @ݕ$YM,˟IjKmQx@Rj igT:7X=twwT/a*LqҶn6EQz$pP JN( [ҳ+_^U `"NYݟz   l_/?Bɐ蠴rpǢV_ZBLd]k#3+v˕&.L&L4z; qҢ[vJN]x-L  `@@Qz |O$2ڮJ, ZeUzﬞ/KsG5M4nXQOT䟻ut貆 v<^,!15M*ȧDW g밉;Yٯ2sRr"%3VMϜ&X&yy7m?/O I9iUĒ$= 뭵[R&~&c쥪.)B.;o#}ҙ]Qвrj|o=R/(efXMYHh014399J:JmmmTxz1qto[fgg_`J&Bynic NްVϱf-4mI>9}W21=+`P7ZfmGcZ! d!(ra[JP#pj:::|+6 ^mvے_y]!}~^gEБ:ٰJ<`BypXZjAFU$0`WhҾt ~|q^ŪU)h(D?rBjrIb%QQLJhqJ-s(L|K(ro0%Izƿf+6:oy24M[栒LL==%୆r4M;`0Rzzp|:_枞ٝOA#X zw+_Zl~I,_M~=ikl,v:t2`*xJ}Tiga8EyX$\ Bkٹwм$ s}9;- Mk/XJ wT+;bᒱH8|[q}n&Sߑჩ8ZGfcl(;NeuX(fR䥢*3'"]X*1\[q&ifNhmKuЪl+]_hh-H_nu3NĸHye_蠴0sܾkEt]}\AA^^MkW J s}n/KRNoU.4o+"}fA('\/{BlIr+™`Eу5%xUu"~&zcua~%NDw{U5VAg+H5dm;D2sxe7, 3_\EEu Œ)@̣{/ΪϳaX+M U@IENDB`AntiMicroX-antimicrox-b300273/src/000077500000000000000000000000001471077622000167415ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/antimicrosettings.cpp000066400000000000000000000062661471077622000232250ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "antimicrosettings.h" #include const bool AntiMicroSettings::defaultDisabledWinEnhanced = false; AntiMicroSettings::AntiMicroSettings(const QString &fileName, Format format, QObject *parent) : QSettings(fileName, format, parent) { } /** * @brief Get the currently used value such as an setting overridden * with a command line argument. * @param Setting key * @param Default value to use if key does not exist * @return Stored value or the default value passed */ QVariant AntiMicroSettings::runtimeValue(const QString &key, const QVariant &defaultValue) const { QVariant settingValue; QString inGroup = group(); QString fullKey = QString(inGroup).append("/").append(key); if (cmdSettings.contains(fullKey)) settingValue = cmdSettings.value(fullKey, defaultValue); else settingValue = value(key, defaultValue); return settingValue; } /** * @brief Import relevant options given on the command line into a QSettings * instance. Used to override any options that might be present in the * main settings file. Keys will have to be changed to the appropriate * config key. * @param Interpreted options set on the command line. */ void AntiMicroSettings::importFromCommandLine(CommandLineUtility &cmdutility) { getCmdSettings().clear(); if (cmdutility.isLaunchInTrayEnabled()) { getCmdSettings().setValue("LaunchInTray", 1); } } /** * @brief applies settings from command line to logger * * @param cmdutility * @param logger pointer to logger, if nullptr then getInstance() is used */ void AntiMicroSettings::applySettingsToLogger(CommandLineUtility &cmdutility, Logger *logger_ptr) { if (logger_ptr == nullptr) logger_ptr = Logger::getInstance(); if (cmdutility.getCurrentLogLevel() != Logger::LOG_NONE) { logger_ptr->setLogLevel(cmdutility.getCurrentLogLevel()); } else if (contains("LogLevel")) { logger_ptr->setLogLevel(static_cast(value("LogLevel").toInt())); } if (!cmdutility.getCurrentLogFile().isEmpty()) { logger_ptr->setCurrentLogFile(cmdutility.getCurrentLogFile()); } else if (contains("LogFile")) { logger_ptr->setCurrentLogFile(value("LogFile").toString()); } } QMutex *AntiMicroSettings::getLock() { return &lock; } QSettings &AntiMicroSettings::getCmdSettings() { return cmdSettings; } AntiMicroX-antimicrox-b300273/src/antimicrosettings.h000066400000000000000000000030171471077622000226610ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ANTIMICROSETTINGS_H #define ANTIMICROSETTINGS_H #include "commandlineutility.h" #include class AntiMicroSettings : public QSettings { Q_OBJECT public: explicit AntiMicroSettings(const QString &fileName, Format format, QObject *parent = nullptr); QVariant runtimeValue(const QString &key, const QVariant &defaultValue = QVariant()) const; void importFromCommandLine(CommandLineUtility &cmdutility); QMutex *getLock(); QSettings &getCmdSettings(); static const bool defaultDisabledWinEnhanced; void applySettingsToLogger(CommandLineUtility &cmdutility, Logger *logger = nullptr); protected: QSettings cmdSettings; QMutex lock; }; #endif // ANTIMICROSETTINGS_H AntiMicroX-antimicrox-b300273/src/antimicrox_windows_icon.rc000066400000000000000000000000621471077622000242240ustar00rootroot00000000000000IDI_ICON1 ICON DISCARDABLE "images/antimicrox.ico"AntiMicroX-antimicrox-b300273/src/antkeymapper.cpp000066400000000000000000000056231471077622000221530ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "antkeymapper.h" #include "eventhandlerfactory.h" #include #include #include AntKeyMapper *AntKeyMapper::_instance = nullptr; static QStringList buildEventGeneratorList() { QStringList temp = QStringList(); #ifdef Q_OS_WIN temp.append("sendinput"); #endif #ifdef WITH_XTEST temp.append("xtest"); #endif #ifdef WITH_UINPUT temp.append("uinput"); #endif return temp; } AntKeyMapper::AntKeyMapper(QString handler, QObject *parent) : QObject(parent) { internalMapper = nullptr; #if defined(Q_OS_UNIX) #ifdef WITH_XTEST if (handler == "xtest") { internalMapper = &x11Mapper; nativeKeyMapper = nullptr; } #endif #ifdef WITH_UINPUT if (handler == "uinput") { internalMapper = &uinputMapper; #ifdef WITH_XTEST nativeKeyMapper = &x11Mapper; #else nativeKeyMapper = nullptr; #endif } #endif #elif defined Q_OS_WIN BACKEND_ELSE_IF(handler == "sendinput") { internalMapper = &winMapper; nativeKeyMapper = 0; } #endif } AntKeyMapper *AntKeyMapper::getInstance(QString handler) { if (_instance == nullptr) { Q_ASSERT(!handler.isEmpty()); QStringList temp = buildEventGeneratorList(); Q_ASSERT(temp.contains(handler)); _instance = new AntKeyMapper(handler); } return _instance; } void AntKeyMapper::deleteInstance() { if (_instance != nullptr) { delete _instance; _instance = nullptr; } } int AntKeyMapper::returnQtKey(int key, int scancode) { return internalMapper->returnQtKey(key, scancode); } int AntKeyMapper::returnVirtualKey(int qkey) { return internalMapper->returnVirtualKey(qkey); } bool AntKeyMapper::isModifierKey(int qkey) { return internalMapper->isModifier(qkey); } QtKeyMapperBase *AntKeyMapper::getNativeKeyMapper() const { return nativeKeyMapper; } QtKeyMapperBase *AntKeyMapper::getKeyMapper() const { return internalMapper; } bool AntKeyMapper::hasNativeKeyMapper() { bool result = (nativeKeyMapper != nullptr); return result; } AntiMicroX-antimicrox-b300273/src/antkeymapper.h000066400000000000000000000036141471077622000216160ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ANTKEYMAPPER_H #define ANTKEYMAPPER_H #include #ifdef Q_OS_WIN #include "qtwinkeymapper.h" #else #ifdef WITH_XTEST #include "qtx11keymapper.h" #endif #ifdef WITH_UINPUT #include "qtuinputkeymapper.h" #endif #endif class AntKeyMapper : public QObject { Q_OBJECT public: static AntKeyMapper *getInstance(QString handler = ""); void deleteInstance(); int returnVirtualKey(int qkey); int returnQtKey(int key, int scancode = 0); bool isModifierKey(int qkey); QtKeyMapperBase *getNativeKeyMapper() const; QtKeyMapperBase *getKeyMapper() const; bool hasNativeKeyMapper(); protected: static AntKeyMapper *_instance; private: explicit AntKeyMapper(QString handler = "", QObject *parent = nullptr); QtKeyMapperBase *internalMapper; QtKeyMapperBase *nativeKeyMapper; #ifdef Q_OS_WIN QtWinKeyMapper winMapper; #else #if defined(WITH_XTEST) QtX11KeyMapper x11Mapper; #endif #if defined(WITH_UINPUT) QtUInputKeyMapper uinputMapper; #endif #endif }; #endif // ANTKEYMAPPER_H AntiMicroX-antimicrox-b300273/src/applaunchhelper.cpp000066400000000000000000000142351471077622000226250ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "applaunchhelper.h" #include "antimicrosettings.h" #include "globalvariables.h" #include "inputdevice.h" #include "joybuttontypes/joybutton.h" #include #include #include #ifdef Q_OS_WIN #include #endif AppLaunchHelper::AppLaunchHelper(AntiMicroSettings *settings, bool graphical, QObject *parent) : QObject(parent) { this->settings = settings; this->graphical = graphical; } void AppLaunchHelper::initRunMethods() { if (graphical) { establishMouseTimerConnections(); enablePossibleMouseSmoothing(); changeMouseRefreshRate(); changeSpringModeScreen(); changeGamepadPollRate(); #ifdef Q_OS_WIN checkPointerPrecision(); #endif } } void AppLaunchHelper::enablePossibleMouseSmoothing() { bool smoothingEnabled = settings->value("Mouse/Smoothing", false).toBool(); if (smoothingEnabled) { int historySize = settings->value("Mouse/HistorySize", 0).toInt(); if (historySize > 0) { JoyButton::setMouseHistorySize(historySize, GlobalVariables::JoyButton::MAXIMUMMOUSEHISTORYSIZE, GlobalVariables::JoyButton::mouseHistorySize, &GlobalVariables::JoyButton::mouseHistoryX, &GlobalVariables::JoyButton::mouseHistoryY); } double weightModifier = settings->value("Mouse/WeightModifier", 0.0).toDouble(); if (weightModifier > 0.0) { JoyButton::setWeightModifier(weightModifier, GlobalVariables::JoyButton::MAXIMUMWEIGHTMODIFIER, GlobalVariables::JoyButton::weightModifier); } } } void AppLaunchHelper::changeMouseRefreshRate() { int refreshRate = settings->value("Mouse/RefreshRate", 0).toInt(); if (refreshRate > 0) { JoyButton::setMouseRefreshRate(refreshRate, GlobalVariables::JoyButton::mouseRefreshRate, GlobalVariables::JoyButton::IDLEMOUSEREFRESHRATE, JoyButton::getMouseHelper(), &GlobalVariables::JoyButton::mouseHistoryX, &GlobalVariables::JoyButton::mouseHistoryY, JoyButton::getTestOldMouseTime(), JoyButton::getStaticMouseEventTimer()); } } void AppLaunchHelper::changeGamepadPollRate() { int pollRate = settings->value("GamepadPollRate", GlobalVariables::AntimicroSettings::defaultSDLGamepadPollRate).toInt(); if (pollRate > 0) { JoyButton::setGamepadRefreshRate(pollRate, GlobalVariables::JoyButton::gamepadRefreshRate, JoyButton::getMouseHelper()); } } void AppLaunchHelper::printControllerList(QMap *joysticks) { PRINT_STDOUT() << QObject::tr("# of joysticks found: %1").arg(joysticks->size()) << "\n" << "\n" << QObject::tr("List Joysticks:") << "\n" << QObject::tr("---------------") << "\n"; QMapIterator iter(*joysticks); int indexNumber = 1; while (iter.hasNext()) { InputDevice *tempdevice = iter.next().value(); PRINT_STDOUT() << QObject::tr("Joystick %1:").arg(indexNumber) << "\n" << tempdevice->getDescription(); if (iter.hasNext()) { PRINT_STDOUT() << "\n"; indexNumber++; } } } void AppLaunchHelper::changeSpringModeScreen() { int springScreen = settings->value("Mouse/SpringScreen", GlobalVariables::AntimicroSettings::defaultSpringScreen).toInt(); if (springScreen >= QGuiApplication::screens().count()) { springScreen = -1; settings->setValue("Mouse/SpringScreen", GlobalVariables::AntimicroSettings::defaultSpringScreen); settings->sync(); } JoyButton::setSpringModeScreen(springScreen, GlobalVariables::JoyButton::springModeScreen); } #ifdef Q_OS_WIN void AppLaunchHelper::checkPointerPrecision() { WinExtras::grabCurrentPointerPrecision(); bool disableEnhandedPoint = settings->value("Mouse/DisableWinEnhancedPointer", AntiMicroSettings::defaultDisabledWinEnhanced).toBool(); if (disableEnhandedPoint) { WinExtras::disablePointerPrecision(); } } void AppLaunchHelper::appQuitPointerPrecision() { bool disableEnhancedPoint = settings->value("Mouse/DisableWinEnhancedPointer", AntiMicroSettings::defaultDisabledWinEnhanced).toBool(); if (disableEnhancedPoint && !WinExtras::isUsingEnhancedPointerPrecision()) { WinExtras::enablePointerPrecision(); } } #endif void AppLaunchHelper::revertMouseThread() { JoyButton::indirectStaticMouseThread(QThread::currentThread(), JoyButton::getStaticMouseEventTimer(), JoyButton::getMouseHelper()); } void AppLaunchHelper::changeMouseThread(QThread *thread) { JoyButton::setStaticMouseThread(thread, JoyButton::getStaticMouseEventTimer(), JoyButton::getTestOldMouseTime(), GlobalVariables::JoyButton::IDLEMOUSEREFRESHRATE, JoyButton::getMouseHelper()); } void AppLaunchHelper::establishMouseTimerConnections() { JoyButton::establishMouseTimerConnections(); } AntiMicroSettings *AppLaunchHelper::getSettings() const { return settings; } AntiMicroX-antimicrox-b300273/src/applaunchhelper.h000066400000000000000000000034241471077622000222700ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef APPLAUNCHHELPER_H #define APPLAUNCHHELPER_H #include #include class AntiMicroSettings; class InputDevice; class QThread; class AppLaunchHelper : public QObject { Q_OBJECT public: explicit AppLaunchHelper(AntiMicroSettings *settings, bool graphical = false, QObject *parent = 0); void printControllerList(QMap *joysticks); AntiMicroSettings *getSettings() const; protected: void enablePossibleMouseSmoothing(); void establishMouseTimerConnections(); void changeMouseRefreshRate(); void changeSpringModeScreen(); void changeGamepadPollRate(); #ifdef Q_OS_WIN void checkPointerPrecision(); #endif public slots: #ifdef Q_OS_WIN void appQuitPointerPrecision(); #endif void initRunMethods(); void revertMouseThread(); void changeMouseThread(QThread *thread); private: AntiMicroSettings *settings; bool graphical; }; #endif // APPLAUNCHHELPER_H AntiMicroX-antimicrox-b300273/src/autoprofileinfo.cpp000066400000000000000000000102541471077622000226540ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "autoprofileinfo.h" #include #include AutoProfileInfo::AutoProfileInfo(QString uniqueID, QString profileLocation, QString exe, bool active, bool partialTitle, QObject *parent) : QObject(parent) { setUniqueID(uniqueID); setProfileLocation(profileLocation); setExe(exe); setActive(active); setDefaultState(false); setPartialState(partialTitle); } AutoProfileInfo::AutoProfileInfo(QString uniqueID, QString profileLocation, bool active, bool partialTitle, QObject *parent) : QObject(parent) { setUniqueID(uniqueID); setProfileLocation(profileLocation); setActive(active); setDefaultState(false); setPartialState(partialTitle); } AutoProfileInfo::AutoProfileInfo(QObject *parent) : QObject(parent) { setActive(true); setDefaultState(false); setPartialState(false); } AutoProfileInfo::~AutoProfileInfo() {} void AutoProfileInfo::setUniqueID(QString uniqueID) { this->uniqueID = uniqueID; } QString AutoProfileInfo::getUniqueID() const { return uniqueID; } void AutoProfileInfo::setProfileLocation(QString profileLocation) { QFileInfo info(profileLocation); if ((profileLocation != this->profileLocation) && info.exists() && info.isReadable()) { this->profileLocation = profileLocation; } else if (profileLocation.isEmpty()) { this->profileLocation = ""; } } QString AutoProfileInfo::getProfileLocation() const { return profileLocation; } void AutoProfileInfo::setExe(QString exe) { if (!exe.isEmpty()) { QFileInfo info(exe); if ((exe != this->exe) && info.exists() && info.isExecutable()) { this->exe = exe; } #ifdef Q_OS_WIN else if (exe != this->exe && info.suffix() == "exe") { this->exe = exe; } #endif } else { this->exe = exe; } } QString AutoProfileInfo::getExe() const { return exe; } void AutoProfileInfo::setWindowClass(QString windowClass) { this->windowClass = windowClass; } QString AutoProfileInfo::getWindowClass() const { return windowClass; } void AutoProfileInfo::setWindowName(QString winName) { this->windowName = winName; } QString AutoProfileInfo::getWindowName() const { return windowName; } void AutoProfileInfo::setActive(bool active) { this->active = active; } bool AutoProfileInfo::isActive() { return active; } void AutoProfileInfo::setDefaultState(bool value) { this->defaultState = value; } /** * @brief is this autoprofile loaded by default? * There is one default profile for all of controllers and there can be also some default profiles for selected controllers */ bool AutoProfileInfo::isCurrentDefault() { return defaultState; } void AutoProfileInfo::setDeviceName(QString name) { this->deviceName = name; } QString AutoProfileInfo::getDeviceName() const { if (deviceName.isNull()) return ""; else return deviceName; } void AutoProfileInfo::setPartialState(bool value) { this->partialState = value; } bool AutoProfileInfo::isPartialState() { return partialState; } QString AutoProfileInfo::toString() const { return QString("ID of assigned controller:%1, Profile Location:%2, Exe:%3,WindowClass:%4, WindowName:%5, isActive:%6, " "DeviceName:%7") .arg(uniqueID, profileLocation, exe, windowClass, windowName, active ? "true" : "false", deviceName); } AntiMicroX-antimicrox-b300273/src/autoprofileinfo.h000066400000000000000000000047221471077622000223240ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef AUTOPROFILEINFO_H #define AUTOPROFILEINFO_H #include /** * @brief Links information about targeted application with recommended profile. * * Used by AutoProfileWatcher as a part of implementation on auto profile functionality. */ class AutoProfileInfo : public QObject { Q_OBJECT public: explicit AutoProfileInfo(QString uniqueID, QString profileLocation, bool active, bool partialTitle, QObject *parent); explicit AutoProfileInfo(QString uniqueID, QString profileLocation, QString exe, bool active, bool partialTitle, QObject *parent); explicit AutoProfileInfo(QObject *parent); ~AutoProfileInfo(); void setUniqueID(QString guid); QString getUniqueID() const; void setProfileLocation(QString profileLocation); QString getProfileLocation() const; void setExe(QString exe); QString getExe() const; void setWindowClass(QString windowClass); QString getWindowClass() const; void setWindowName(QString winName); QString getWindowName() const; void setActive(bool active); bool isActive(); void setDeviceName(QString name); QString getDeviceName() const; void setDefaultState(bool value); bool isCurrentDefault(); void setPartialState(bool value); bool isPartialState(); QString toString() const; private: QString uniqueID; // unique ID of assigned controller (all, when none) QString profileLocation; QString exe; QString deviceName; QString windowClass; QString windowName; bool active; bool defaultState; bool partialState; }; Q_DECLARE_METATYPE(AutoProfileInfo *) #endif // AUTOPROFILEINFO_H AntiMicroX-antimicrox-b300273/src/autoprofilewatcher.cpp000066400000000000000000000545431471077622000233670ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "autoprofilewatcher.h" #include "antimicrosettings.h" #include "autoprofileinfo.h" #include #include #include #include #include #if defined(Q_OS_UNIX) && defined(WITH_X11) #include "x11extras.h" #elif defined(Q_OS_WIN) #include "winextras.h" #endif AutoProfileWatcher *AutoProfileWatcher::_instance = nullptr; QTimer AutoProfileWatcher::checkWindowTimer; AutoProfileWatcher::AutoProfileWatcher(AntiMicroSettings *settings, QObject *parent) : QObject(parent) { this->settings = settings; allDefaultInfo = nullptr; currentApplication = ""; _instance = this; syncProfileAssignment(); connect(&(checkWindowTimer), &QTimer::timeout, _instance, &AutoProfileWatcher::runAppCheck); } AutoProfileWatcher::~AutoProfileWatcher() { if (checkWindowTimer.isActive()) { checkWindowTimer.stop(); disconnect(&(checkWindowTimer), &QTimer::timeout, _instance, nullptr); } _instance = nullptr; } AutoProfileWatcher *AutoProfileWatcher::getAutoProfileWatcherInstance() { return _instance; } void AutoProfileWatcher::disconnectWindowTimer() { checkWindowTimer.stop(); disconnect(&(checkWindowTimer), &QTimer::timeout, _instance, nullptr); } void AutoProfileWatcher::startTimer() { checkWindowTimer.start(CHECKTIME); } void AutoProfileWatcher::stopTimer() { checkWindowTimer.stop(); } void AutoProfileWatcher::runAppCheck() { qDebug() << qApp->applicationFilePath(); QString appLocation = QString(); QString baseAppFileName = QString(); getUniqeIDSetLocal().clear(); // Check whether program path needs to be parsed. Removes processing time // and need to run Linux specific code searching /proc. #ifdef Q_OS_LINUX if (!appProfileAssignments.isEmpty()) { appLocation = findAppLocation(); } #else // In Windows, get program location no matter what. appLocation = findAppLocation(); if (!appLocation.isEmpty()) { baseAppFileName = QFileInfo(appLocation).fileName(); } #endif qDebug() << "appLocation is " << appLocation; // More portable check for whether antimicrox is the current application // with focus. QWidget *focusedWidget = qApp->activeWindow(); if (focusedWidget != nullptr) qDebug() << "get active window of app"; QString nowWindow = QString(); QString nowWindowClass = QString(); QString nowWindowName = QString(); #ifdef Q_OS_WIN nowWindowName = WinExtras::getCurrentWindowText(); #else long currentWindow = X11Extras::getInstance()->getWindowInFocus(); qDebug() << "getWindowInFocus: " << currentWindow; if (currentWindow > 0) { long tempWindow = X11Extras::getInstance()->findParentClient(currentWindow); qDebug() << "findParentClient: " << tempWindow; if (tempWindow > 0) currentWindow = tempWindow; nowWindow = QString::number(currentWindow); qDebug() << "number of window now: " << nowWindow; nowWindowClass = X11Extras::getInstance()->getWindowClass(static_cast(currentWindow)); qDebug() << "class of window now: " << nowWindowClass; nowWindowName = X11Extras::getInstance()->getWindowTitle(static_cast(currentWindow)); qDebug() << "title of window now: " << nowWindowName; } qDebug() << "WINDOW CLASS: " << nowWindowClass; qDebug() << "WINDOW IN FOCUS: " << nowWindow; #endif qDebug() << "WINDOW NAME: " << nowWindowName; bool checkForTitleChange = getWindowNameProfileAssignments().size() > 0; qDebug() << "window profile assignments size: " << getWindowNameProfileAssignments().size(); qDebug() << "checkForTitleChange: " << checkForTitleChange; #ifdef Q_OS_WIN if (!focusedWidget && ((!appLocation.isEmpty() && appLocation != currentApplication) || (checkForTitleChange && nowWindowName != currentAppWindowTitle))) #else if (!focusedWidget && ((!nowWindow.isEmpty() && nowWindow != currentApplication) || (checkForTitleChange && nowWindowName != currentAppWindowTitle))) #endif { #ifdef Q_OS_WIN currentApplication = appLocation; #else currentApplication = nowWindow; #endif currentAppWindowTitle = nowWindowName; qInfo() << QString("Active window changed to: Title = \"%1\", " "Class = \"%2\", Program = \"%3\" or \"%4\".") .arg(nowWindowName, nowWindowClass, appLocation, baseAppFileName); QSet fullSet; if (!appLocation.isEmpty() && getAppProfileAssignments().contains(appLocation)) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) auto templist = getAppProfileAssignments().value(appLocation); QSet tempSet(templist.begin(), templist.end()); #else QSet tempSet; tempSet = getAppProfileAssignments().value(appLocation).toSet(); #endif fullSet.unite(tempSet); } else if (!baseAppFileName.isEmpty() && getAppProfileAssignments().contains(baseAppFileName)) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) auto templist = getAppProfileAssignments().value(baseAppFileName); QSet tempSet(templist.begin(), templist.end()); #else QSet tempSet; tempSet = getAppProfileAssignments().value(baseAppFileName).toSet(); #endif fullSet.unite(tempSet); } if (!nowWindowClass.isEmpty() && getWindowClassProfileAssignments().contains(nowWindowClass)) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) auto templist = getWindowClassProfileAssignments().value(nowWindowClass); QSet tempSet(templist.begin(), templist.end()); #else QSet tempSet; tempSet = getWindowClassProfileAssignments().value(nowWindowClass).toSet(); #endif fullSet.unite(tempSet); } // part window title if (!nowWindowName.isEmpty()) { QHashIterator> iter(getWindowNameProfileAssignments()); while (iter.hasNext()) { iter.next(); bool hasOnePartName = false; for (auto autoInfo : iter.value()) { if (autoInfo->isPartialState()) { hasOnePartName = true; break; } } if (hasOnePartName) { qDebug() << "IT HAS A PARTIAL TITLE NAME"; if (nowWindowName.contains(iter.key())) { qDebug() << "WINDOW: \"" << nowWindowName << "\" includes \"" << iter.key() << "\""; QSet tempSet; QList list = iter.value(); #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) tempSet = QSet(list.begin(), list.end()); #else tempSet = list.toSet(); #endif fullSet = fullSet.unite(tempSet); } else { qDebug() << "WINDOW: \"" << nowWindowName << "\" doesn't include \"" << iter.key() << "\""; } } else { qDebug() << "IT HAS A FULL TITLE NAME"; if (iter.key() == nowWindowName) { qDebug() << "WINDOW: \"" << nowWindowName << "\" is equal to hash key: \"" << iter.key() << "\""; #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) auto templist = getWindowNameProfileAssignments().value(nowWindowName); QSet tempSet(templist.begin(), templist.end()); #else QSet tempSet; tempSet = getWindowNameProfileAssignments().value(nowWindowName).toSet(); #endif fullSet = fullSet.unite(tempSet); } else { qDebug() << "WINDOW: \"" << nowWindowName << "\" is not equal to hash key: \"" << iter.key() << "\""; } } } } QHash highestMatchCount; QHash highestMatches; for (auto &&info : fullSet) { if (info->isActive()) { int numProps = 0; numProps += !info->getExe().isEmpty() ? 1 : 0; numProps += !info->getWindowClass().isEmpty() ? 1 : 0; numProps += !info->getWindowName().isEmpty() ? 1 : 0; int numMatched = 0; numMatched += (!info->getExe().isEmpty() && (info->getExe() == appLocation || info->getExe() == baseAppFileName)) ? 1 : 0; numMatched += (!info->getWindowClass().isEmpty() && info->getWindowClass() == nowWindowClass) ? 1 : 0; if (info->isPartialState()) { numMatched += (!info->getWindowName().isEmpty() && nowWindowName.contains(info->getWindowName())) ? 1 : 0; } else { numMatched += (!info->getWindowName().isEmpty() && info->getWindowName() == nowWindowName) ? 1 : 0; } if (numProps == numMatched && highestMatchCount.contains(info->getUniqueID())) { int currentHigh = highestMatchCount.value(info->getUniqueID()); if (numMatched > currentHigh) { highestMatchCount.insert(info->getUniqueID(), numMatched); highestMatches.insert(info->getUniqueID(), info); } } else if (numProps == numMatched && !highestMatchCount.contains(info->getUniqueID())) { highestMatchCount.insert(info->getUniqueID(), numMatched); highestMatches.insert(info->getUniqueID(), info); } } } for (auto &&info : highestMatches) { getUniqeIDSetLocal().insert(info->getUniqueID()); emit foundApplicableProfile(info); } if ((!getDefaultProfileAssignments().isEmpty() || allDefaultInfo) && !focusedWidget) { if (allDefaultInfo != nullptr && allDefaultInfo->isActive() && !getUniqeIDSetLocal().contains("all")) { emit foundApplicableProfile(allDefaultInfo); } for (auto &&info : getDefaultProfileAssignments()) { if (info->isActive() && !getUniqeIDSetLocal().contains(info->getUniqueID())) { emit foundApplicableProfile(info); } } } } } void AutoProfileWatcher::syncProfileAssignment() { clearProfileAssignments(); currentApplication = ""; settings->getLock()->lock(); settings->beginGroup("DefaultAutoProfiles"); QString exe = QString(); QString uniqueID = QString(); QString profile = QString(); QString active = QString(); QString windowClass = QString(); QString windowName = QString(); QStringList registeredUniques = settings->value("Uniques", QStringList()).toStringList(); settings->endGroup(); QString allProfile = settings->value(QString("DefaultAutoProfileAll/Profile"), "all").toString(); QString allActive = settings->value(QString("DefaultAutoProfileAll/Active"), "0").toString(); // Handle overall Default profile assignment bool defaultActive = allActive == "1" ? true : false; if (defaultActive) { allDefaultInfo = new AutoProfileInfo("all", allProfile, defaultActive, 0, this); allDefaultInfo->setDefaultState(true); } // Handle device specific Default profile assignments for (auto &&tempkey : registeredUniques) { QString uniqueID = QString(tempkey).replace("UniqueID", ""); QString profile = settings->value(QString("DefaultAutoProfile-%1/Profile").arg(uniqueID), "").toString(); QString active = settings->value(QString("DefaultAutoProfile-%1/Active").arg(uniqueID), "").toString(); QString exe = settings->value(QString("DefaultAutoProfile-%1/Exe").arg(uniqueID), "").toString(); QString partialTitle = settings->value(QString("DefaultAutoProfile-%1/PartialTitle").arg(uniqueID), "").toString(); QString windowClass = settings->value(QString("DefaultAutoProfile-%1/WindowClass").arg(uniqueID), "").toString(); QString windowName = settings->value(QString("DefaultAutoProfile-%1/WindowName").arg(uniqueID), "").toString(); // need to change when it's needed to add windowClass, title and partial name if (!uniqueID.isEmpty() && !profile.isEmpty()) { bool profileActive = active == "1" ? true : false; if (profileActive && uniqueID != "all") { AutoProfileInfo *info = new AutoProfileInfo(uniqueID, profile, profileActive, 0, this); info->setExe(exe); info->setWindowName(windowName); info->setWindowClass(windowClass); info->setPartialState(partialTitle == "1" ? true : false); info->setDefaultState(true); defaultProfileAssignments.insert(uniqueID, info); } } } settings->beginGroup("AutoProfiles"); bool quitSearch = false; for (int i = 1; !quitSearch; i++) { exe = settings->value(QString("AutoProfile%1Exe").arg(i), "").toString(); exe = QDir::toNativeSeparators(exe); convToUniqueIDAutoProfGroupSett(settings, QString("AutoProfile%1GUID").arg(i), QString("AutoProfile%1UniqueID").arg(i)); uniqueID = settings->value(QString("AutoProfile%1UniqueID").arg(i), "").toString(); profile = settings->value(QString("AutoProfile%1Profile").arg(i), "").toString(); active = settings->value(QString("AutoProfile%1Active").arg(i), 0).toString(); windowName = settings->value(QString("AutoProfile%1WindowName").arg(i), "").toString(); QString partialTitle = settings->value(QString("AutoProfile%1PartialTitle").arg(i), 0).toString(); bool partialTitleBool = partialTitle == "1" ? true : false; #ifdef Q_OS_UNIX windowClass = settings->value(QString("AutoProfile%1WindowClass").arg(i), "").toString(); #else windowClass.clear(); #endif // Check if all required elements exist. If not, assume that the end of the // list has been reached. if ((!exe.isEmpty() || !windowClass.isEmpty() || !windowName.isEmpty()) && !uniqueID.isEmpty()) { bool profileActive = active == "1" ? true : false; if (profileActive) { AutoProfileInfo *info = new AutoProfileInfo(uniqueID, profile, profileActive, partialTitleBool, this); if (!windowClass.isEmpty()) { info->setWindowClass(windowClass); QList templist; if (getWindowClassProfileAssignments().contains(windowClass)) templist = getWindowClassProfileAssignments().value(windowClass); templist.append(info); windowClassProfileAssignments.insert(windowClass, templist); } // partly watching is needed for window title if (!windowName.isEmpty()) { info->setWindowName(windowName); qDebug() << "WINDOW NAME IN AUTOPROFILEWATCHER: " << windowName; QList templist; QHashIterator> windows(getWindowNameProfileAssignments()); qDebug() << "getWindowNameProfileAssignments contains such elements like: "; while (windows.hasNext()) { windows.next(); qDebug() << windows.key(); } if (getWindowNameProfileAssignments().contains(windowName)) { qDebug() << "getWindowNameProfileAssignments contains " << windowName; templist = getWindowNameProfileAssignments().value(windowName); } else { qDebug() << "getWindowNameProfileAssignments doesn't contain " << windowName; } templist.append(info); windowNameProfileAssignments.insert(windowName, templist); } if (!exe.isEmpty()) { info->setExe(exe); QList templist; if (getAppProfileAssignments().contains(exe)) templist = appProfileAssignments.value(exe); templist.append(info); appProfileAssignments.insert(exe, templist); QString baseExe = QFileInfo(exe).fileName(); if (!baseExe.isEmpty() && baseExe != exe) { QList templist; if (getAppProfileAssignments().contains(baseExe)) templist = getAppProfileAssignments().value(baseExe); templist.append(info); appProfileAssignments.insert(baseExe, templist); } } } } else { quitSearch = true; } } settings->endGroup(); settings->getLock()->unlock(); } void AutoProfileWatcher::clearProfileAssignments() { QSet terminateProfiles; for (const auto &profileList : appProfileAssignments.values()) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) terminateProfiles.unite(QSet(profileList.begin(), profileList.end())); #else terminateProfiles.unite(profileList.toSet()); #endif } appProfileAssignments.clear(); for (const auto &profileList : windowClassProfileAssignments.values()) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) terminateProfiles.unite(QSet(profileList.begin(), profileList.end())); #else terminateProfiles.unite(profileList.toSet()); #endif } windowClassProfileAssignments.clear(); for (const auto &profileList : windowNameProfileAssignments.values()) { #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) terminateProfiles.unite(QSet(profileList.begin(), profileList.end())); #else terminateProfiles.unite(profileList.toSet()); #endif } windowNameProfileAssignments.clear(); for (auto *info : terminateProfiles) { if (info != nullptr) { info->deleteLater(); info = nullptr; } } for (auto *info : getDefaultProfileAssignments().values()) { if (info != nullptr) { info->deleteLater(); info = nullptr; } } defaultProfileAssignments.clear(); allDefaultInfo = nullptr; getUniqeIDSetLocal().clear(); } QString AutoProfileWatcher::findAppLocation() { QString exepath = QString(); #if defined(Q_OS_LINUX) #ifdef WITH_X11 Window currentWindow = 0; int pid = 0; currentWindow = X11Extras::getInstance()->getWindowInFocus(); if (currentWindow) pid = X11Extras::getInstance()->getApplicationPid(currentWindow); if (pid > 0) exepath = X11Extras::getInstance()->getApplicationLocation(pid); #endif #elif defined(Q_OS_WIN) exepath = WinExtras::getForegroundWindowExePath(); #endif return exepath; } QList *AutoProfileWatcher::getCustomDefaults() { QList *temp = new QList(); QHashIterator iter(getDefaultProfileAssignments()); while (iter.hasNext()) { iter.next(); temp->append(iter.value()); } return temp; } AutoProfileInfo *AutoProfileWatcher::getDefaultAllProfile() { return allDefaultInfo; } bool AutoProfileWatcher::isUniqueIDLocked(QString uniqueID) { return getUniqeIDSetLocal().contains(uniqueID); } QHash> const &AutoProfileWatcher::getAppProfileAssignments() { return appProfileAssignments; } QHash> const &AutoProfileWatcher::getWindowClassProfileAssignments() { return windowClassProfileAssignments; } QHash> const &AutoProfileWatcher::getWindowNameProfileAssignments() { return windowNameProfileAssignments; } QHash const &AutoProfileWatcher::getDefaultProfileAssignments() { return defaultProfileAssignments; } QSet &AutoProfileWatcher::getUniqeIDSetLocal() { return uniqueIDSet; } void AutoProfileWatcher::convToUniqueIDAutoProfGroupSett(QSettings *sett, QString guidAutoProfSett, QString uniqueAutoProfSett) { if (sett->contains(guidAutoProfSett)) { sett->setValue(uniqueAutoProfSett, sett->value(guidAutoProfSett)); sett->remove(guidAutoProfSett); } } AntiMicroX-antimicrox-b300273/src/autoprofilewatcher.h000066400000000000000000000061401471077622000230220ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef AUTOPROFILEWATCHER_H #define AUTOPROFILEWATCHER_H #include #include #include class AntiMicroSettings; class AutoProfileInfo; class QSettings; /** * @brief Manages auto profile functionality. Allows for profiles to be associated with specific applications. * * Watches currently focused window and changes current set to pre-defined one when app is recognized. */ class AutoProfileWatcher : public QObject { Q_OBJECT public: explicit AutoProfileWatcher(AntiMicroSettings *settings, QObject *parent = nullptr); ~AutoProfileWatcher(); void startTimer(); void stopTimer(); static void disconnectWindowTimer(); static AutoProfileWatcher *getAutoProfileWatcherInstance(); QList *getCustomDefaults(); AutoProfileInfo *getDefaultAllProfile(); // bool isGUIDLocked(QString guid); bool isUniqueIDLocked(QString uniqueID); QHash> const &getAppProfileAssignments(); QHash> const &getWindowClassProfileAssignments(); QHash> const &getWindowNameProfileAssignments(); QHash const &getDefaultProfileAssignments(); static const int CHECKTIME = 500; // time in ms protected: QString findAppLocation(); void clearProfileAssignments(); void convToUniqueIDAutoProfGroupSett(QSettings *sett, QString guidAutoProfSett, QString uniqueAutoProfSett); signals: void foundApplicableProfile(AutoProfileInfo *info); public slots: void syncProfileAssignment(); private slots: void runAppCheck(); private: // QSet& getGuidSetLocal(); QSet &getUniqeIDSetLocal(); static AutoProfileWatcher *_instance; static QTimer checkWindowTimer; AntiMicroSettings *settings; QHash> appProfileAssignments; QHash> windowClassProfileAssignments; QHash> windowNameProfileAssignments; QHash defaultProfileAssignments; AutoProfileInfo *allDefaultInfo; QString currentApplication; QString currentAppWindowTitle; // QSet guidSet; QSet uniqueIDSet; }; #endif // AUTOPROFILEWATCHER_H AntiMicroX-antimicrox-b300273/src/axisvaluebox.cpp000066400000000000000000000202531471077622000221610ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "axisvaluebox.h" #include "globalvariables.h" #include "joyaxis.h" #include #include #include #include #include AxisValueBox::AxisValueBox(QWidget *parent) : QWidget(parent) { m_axis = nullptr; m_deadZone = 0; m_maxZone = 0; joyValue = 0; m_throttle = 0; lboxstart = 0; lboxend = 0; rboxstart = 0; rboxend = 0; boxwidth = 0; boxheight = 0; singlewidth = 0; singleend = 0; } void AxisValueBox::setThrottle(int throttle) { qDebug() << "throttle value at start of function setThrottle: " << throttle; if ((throttle <= static_cast(JoyAxis::PositiveHalfThrottle)) && (throttle >= static_cast(JoyAxis::NegativeHalfThrottle))) { qDebug() << "throttle variable has been set in setThrottle with: " << throttle; m_throttle = throttle; setValue(joyValue); } update(); } void AxisValueBox::setValue(int value) { qDebug() << "Value for axis from value box at start is: " << value; qDebug() << "throttle variable has value: " << m_throttle; if ((value >= GlobalVariables::JoyAxis::AXISMIN) && (value <= GlobalVariables::JoyAxis::AXISMAX)) { qDebug() << "Value for axis from value box is between : " << GlobalVariables::JoyAxis::AXISMIN << " and " << GlobalVariables::JoyAxis::AXISMAX; switch (m_throttle) { case -2: this->joyValue = (value <= 0) ? value : (-value); break; case -1: this->joyValue = ((value + GlobalVariables::JoyAxis::AXISMIN) / 2); break; case 0: this->joyValue = value; break; case 1: this->joyValue = (value + GlobalVariables::JoyAxis::AXISMAX) / 2; break; case 2: this->joyValue = (value >= 0) ? value : (-value); break; } } update(); } void AxisValueBox::setValue(JoyAxis *axis, int value) { m_axis = axis; qDebug() << "Value for axis from value box at start is: " << value; qDebug() << "throttle variable has value: " << m_throttle; if ((value >= GlobalVariables::JoyAxis::AXISMIN) && (value <= GlobalVariables::JoyAxis::AXISMAX)) { qDebug() << "Value for axis from value box is between : " << GlobalVariables::JoyAxis::AXISMIN << " and " << GlobalVariables::JoyAxis::AXISMAX; switch (m_throttle) { case -2: this->joyValue = (value <= 0) ? value : (-value); break; case -1: this->joyValue = ((value + GlobalVariables::JoyAxis::AXISMIN) / 2); break; case 0: this->joyValue = value; break; case 1: this->joyValue = (value + GlobalVariables::JoyAxis::AXISMAX) / 2; break; case 2: this->joyValue = (value >= 0) ? value : (-value); break; } } update(); } void AxisValueBox::setDeadZone(int deadZone) { if ((deadZone >= GlobalVariables::JoyAxis::AXISMIN) && (deadZone <= GlobalVariables::JoyAxis::AXISMAX)) { m_deadZone = deadZone; } update(); } void AxisValueBox::setDeadZone(JoyAxis *axis, int deadZone) { m_axis = axis; if ((deadZone >= GlobalVariables::JoyAxis::AXISMIN) && (deadZone <= GlobalVariables::JoyAxis::AXISMAX)) { m_deadZone = deadZone; } update(); } int AxisValueBox::getDeadZone() { return m_deadZone; } void AxisValueBox::setMaxZone(int maxZone) { if ((maxZone >= GlobalVariables::JoyAxis::AXISMIN) && (maxZone <= GlobalVariables::JoyAxis::AXISMAX)) { m_maxZone = maxZone; } update(); } void AxisValueBox::setMaxZone(JoyAxis *axis, int maxZone) { m_axis = axis; if ((maxZone >= GlobalVariables::JoyAxis::AXISMIN) && (maxZone <= GlobalVariables::JoyAxis::AXISMAX)) { m_maxZone = maxZone; } update(); } int AxisValueBox::getMaxZone() { return m_maxZone; } int AxisValueBox::getJoyValue() { return joyValue; } int AxisValueBox::getThrottle() { return m_throttle; } void AxisValueBox::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); boxwidth = (this->width() / 2) - 5; boxheight = this->height() - 4; lboxstart = 0; lboxend = lboxstart + boxwidth; rboxstart = lboxend + 10; rboxend = rboxstart + boxwidth; singlewidth = this->width(); singleend = lboxstart + singlewidth; } void AxisValueBox::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter paint(this); paint.setPen(palette().base().color()); paint.setBrush(palette().base().color()); QBrush brush(palette().light().color()); if (m_throttle == 0) { qDrawShadeRect(&paint, lboxstart, 0, lboxend, height(), palette(), true, 2, 0, &brush); qDrawShadeRect(&paint, rboxstart, 0, rboxend, height(), palette(), true, 2, 0, &brush); } else { qDrawShadeRect(&paint, lboxstart, 0, singlewidth, height(), palette(), true, 2, 0, &brush); } QColor innerColor; if (abs(joyValue) <= m_deadZone) { innerColor = Qt::gray; } else if (abs(joyValue) >= m_maxZone) { innerColor = Qt::red; } else { innerColor = Qt::blue; } paint.setPen(innerColor); paint.setBrush(innerColor); int barwidth = (m_throttle == 0) ? boxwidth : singlewidth; int barlength = abs((barwidth - 2) * joyValue) / getMaxAxValue(); if (joyValue > 0) { paint.drawRect(((m_throttle == 0) ? rboxstart : lboxstart) + 2, 2, barlength, boxheight); } else if (joyValue < 0) { paint.drawRect(lboxstart + barwidth - 2 - barlength, 2, barlength, boxheight); } // Draw marker for deadZone int deadLine = abs((barwidth - 2) * m_deadZone) / getMaxAxValue(); int maxLine = abs((barwidth - 2) * m_maxZone) / getMaxAxValue(); paint.setPen(Qt::blue); brush.setColor(Qt::blue); QBrush maxBrush(Qt::red); if (m_throttle == static_cast(JoyAxis::NormalThrottle)) { qDrawPlainRect(&paint, rboxstart + 2 + deadLine, 2, 4, boxheight + 2, Qt::black, 1, &brush); qDrawPlainRect(&paint, lboxend - deadLine - 2, 2, 4, boxheight + 2, Qt::black, 1, &brush); paint.setPen(Qt::red); qDrawPlainRect(&paint, rboxstart + 2 + maxLine, 2, 4, boxheight + 2, Qt::black, 1, &maxBrush); qDrawPlainRect(&paint, lboxend - maxLine - 2, 2, 4, boxheight + 2, Qt::black, 1, &maxBrush); } else if ((m_throttle == static_cast(JoyAxis::PositiveThrottle)) || (m_throttle == static_cast(JoyAxis::PositiveHalfThrottle))) { qDrawPlainRect(&paint, lboxstart + deadLine - 2, 2, 4, boxheight + 2, Qt::black, 1, &brush); paint.setPen(Qt::red); qDrawPlainRect(&paint, lboxstart + maxLine, 2, 4, boxheight + 2, Qt::black, 1, &maxBrush); } else if ((m_throttle == static_cast(JoyAxis::NegativeThrottle)) || (m_throttle == static_cast(JoyAxis::NegativeHalfThrottle))) { qDrawPlainRect(&paint, singleend - deadLine - 2, 2, 4, boxheight + 2, Qt::black, 1, &brush); paint.setPen(Qt::red); qDrawPlainRect(&paint, singleend - maxLine, 2, 4, boxheight + 2, Qt::black, 1, &maxBrush); } } int AxisValueBox::getMaxAxValue() { return GlobalVariables::JoyAxis::AXISMAX; } int AxisValueBox::getMinAxValue() { return GlobalVariables::JoyAxis::AXISMIN; } AntiMicroX-antimicrox-b300273/src/axisvaluebox.h000066400000000000000000000035541471077622000216330ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef AXISVALUEBOX_H #define AXISVALUEBOX_H #include class QResizeEvent; class QPaintEvent; class JoyAxis; class AxisValueBox : public QWidget { Q_OBJECT public: explicit AxisValueBox(QWidget *parent = nullptr); int getDeadZone(); int getMaxZone(); int getJoyValue(); int getThrottle(); int getMinAxValue(); int getMaxAxValue(); protected: virtual void resizeEvent(QResizeEvent *event); virtual void paintEvent(QPaintEvent *event); public slots: void setThrottle(int throttle); void setValue(int value); void setValue(JoyAxis *axis, int value); void setDeadZone(int deadZone); void setDeadZone(JoyAxis *axis, int deadZone); void setMaxZone(int maxZone); void setMaxZone(JoyAxis *axis, int deadZone); private: JoyAxis *m_axis; int m_deadZone; int m_maxZone; int joyValue; int m_throttle; int boxwidth; int boxheight; int lboxstart; int lboxend; int rboxstart; int rboxend; int singlewidth; int singleend; }; #endif // AXISVALUEBOX_H AntiMicroX-antimicrox-b300273/src/commandlineutility.cpp000066400000000000000000000374671471077622000234000ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "commandlineutility.h" #include "common.h" #include "eventhandlerfactory.h" #include #include #include #include QStringList CommandLineUtility::eventGeneratorsList = EventHandlerFactory::buildEventGeneratorList(); CommandLineUtility::CommandLineUtility(QObject *parent) : QObject(parent) { launchInTray = false; hideTrayIcon = false; profileLocation = ""; controllerNumber = 0; hiddenRequest = false; showRequest = false; unloadProfile = false; startSetNumber = 0; listControllers = false; currentLogLevel = Logger::LOG_NONE; currentListsIndex = 0; ControllerOptionsInfo tempInfo; controllerOptionsList.append(tempInfo); eventGenerator = EventHandlerFactory::fallBackIdentifier(); } void CommandLineUtility::parseArguments(const QApplication &parsed_app) { QCommandLineParser parser; parser.setApplicationDescription( QCoreApplication::translate("antimicrox", "Graphical program used to map keyboard buttons and mouse controls to " "a " "gamepad. Useful for playing games with no gamepad support.")); parser.addHelpOption(); parser.addVersionOption(); parser.addOptions({ // A boolean option with a single name (-p) {"tray", QCoreApplication::translate("main", "Launch program in system tray only.")}, // A boolean option with multiple names (-f, --force) {"no-tray", QCoreApplication::translate("main", "Launch program with the tray menu disabled")}, // An option with a value {"hidden", QCoreApplication::translate("main", "Launch program without the main window displayed")}, {"show", QCoreApplication::translate( "main", "Show app window when hidden. (Used for unhiding window of already running app instance).")}, {"profile", QCoreApplication::translate("main", "Launch program with the configuration file selected as the default for selected " "controllers, or change active profile of running app. Defaults to all controllers"), QCoreApplication::translate("main", "location")}, {"profile-controller", QCoreApplication::translate("main", "Apply configuration file to a specific controller. Value " "can be a controller index, name, or GUID"), QCoreApplication::translate("main", "value")}, {"unload", QCoreApplication::translate("main", "Unload currently enabled profile(s)"), QCoreApplication::translate("main", "value(s)")}, {"startSet", QCoreApplication::translate("main", "Start joysticks on a specific set. Value can be a " "controller index, name, or GUID"), QCoreApplication::translate("main", "number value")}, {"log-level", QCoreApplication::translate("main", "Enable logging. Levels (from the least strict): warn,info,verbose,debug"), QCoreApplication::translate("main", "log-type")}, {"log-file", QCoreApplication::translate("main", "Choose a file for logs writing"), QCoreApplication::translate("main", "filename")}, {"eventgen", QCoreApplication::translate("main", "Choose between using XTest support and uinput support " "for event generation. Use only if you have " "enabled xtest and uinput options on Linux or vmulti on " "Windows. Default: xtest."), QCoreApplication::translate("main", "event-generation-type"), "xtest"}, // default {{"list", "l"}, QCoreApplication::translate("main", "Print information about joysticks detected by SDL. Use " "only if you have sdl " "library. You can check your controller index, name or " "even GUID.")}, // {"next", // QCoreApplication::translate("main", "Advance profile loading set // options")}, }); parser.process(parsed_app); int i = 0; while ((i < parser.optionNames().count())) { if (parser.isSet("tray")) { qDebug() << "tray is set"; launchInTray = true; hideTrayIcon = false; } else if (parser.isSet("no-tray")) { qDebug() << "no-tray is set"; hideTrayIcon = true; launchInTray = false; } if (parser.isSet("profile")) { parseArgsProfile(parser); } if (parser.isSet("profile-controller")) { parseArgsPrControle(parser); } if (parser.isSet("hidden")) { hiddenRequest = true; } if (parser.isSet("show")) { showRequest = true; } if (parser.isSet("unload")) { parseArgsUnload(parser); } if (parser.isSet("startSet")) { parseArgsStartSet(parser); } if (parser.isSet("next")) { currentListsIndex++; ControllerOptionsInfo tempInfo; controllerOptionsList.append(tempInfo); } if (parser.isSet("list")) { listControllers = true; } #if (defined(WITH_UINPUT) && defined(WITH_XTEST)) if (parser.isSet("eventgen")) { QString eventGenText = parser.value("eventgen"); if (!eventGenText.isEmpty() && !eventGeneratorsList.contains(eventGenText)) { eventGenerator = ""; throw std::runtime_error(QObject::tr("An invalid event generator was specified.").toStdString()); } else if (!eventGenText.isEmpty() && eventGeneratorsList.contains(eventGenText)) { eventGenerator = eventGenText; } else { throw std::runtime_error(QObject::tr("No event generator string was specified.").toStdString()); } } #endif if (parser.isSet("log-level")) { QString logLevelText = parser.value("log-level"); if (logLevelText == "debug") currentLogLevel = Logger::LOG_DEBUG; else if (logLevelText == "verbose") currentLogLevel = Logger::LOG_VERBOSE; else if (logLevelText == "info") currentLogLevel = Logger::LOG_INFO; else if (logLevelText == "warn") currentLogLevel = Logger::LOG_WARNING; else if (logLevelText == "error") currentLogLevel = Logger::LOG_ERROR; else { throw std::runtime_error((QObject::tr("Unknown log level: ") + logLevelText).toStdString()); } } if (parser.isSet("log-file")) { if (!parser.value("log-file").isEmpty()) { currentLogFile = parser.value("log-file"); } else { throw std::runtime_error(QObject::tr("No log file specified.").toStdString()); } } i++; } if (showRequest && hiddenRequest) throw std::runtime_error(QObject::tr("Specified contradicting flags: --show and --hidden").toStdString()); } void CommandLineUtility::parseArgsProfile(const QCommandLineParser &parser) { QFileInfo profileFileInfo(parser.value("profile")); if (profileFileInfo.exists() && (profileFileInfo.suffix() != "amgp") && (profileFileInfo.suffix() != "xml")) { throw std::runtime_error( QObject::tr("Profile location %1 is not an XML file.").arg(parser.value("profile")).toStdString()); } else if (profileFileInfo.exists() && ((profileFileInfo.suffix() == "amgp") || (profileFileInfo.suffix() == "xml"))) { QString tempProfileLocation = profileFileInfo.absoluteFilePath(); qDebug() << "Profile file is set: " << tempProfileLocation; ControllerOptionsInfo tempInfo = getControllerOptionsList().at(currentListsIndex); tempInfo.setProfileLocation(tempProfileLocation); controllerOptionsList.replace(currentListsIndex, tempInfo); } else { throw std::runtime_error( QObject::tr("Profile location %1 does not exist.").arg(parser.value("profile")).toStdString()); } } void CommandLineUtility::parseArgsPrControle(const QCommandLineParser &parser) { bool validNumber = false; int tempNumber = parser.value("profile-controller").toInt(&validNumber); if (validNumber) { if (controllerNumber == 0) controllerNumber = tempNumber; ControllerOptionsInfo tempInfo = getControllerOptionsList().at(currentListsIndex); tempInfo.setControllerNumber(tempNumber); controllerOptionsList.replace(currentListsIndex, tempInfo); } else if (!parser.value("profile-controller").isEmpty()) { if (controllerIDString.isEmpty()) controllerIDString = parser.value("profile-controller"); ControllerOptionsInfo tempInfo = getControllerOptionsList().at(currentListsIndex); tempInfo.setControllerID(parser.value("profile-controller")); controllerOptionsList.replace(currentListsIndex, tempInfo); } else { throw std::runtime_error(QObject::tr("Controller identifier is not a valid value.").toStdString()); } } void CommandLineUtility::parseArgsUnload(const QCommandLineParser &parser) { ControllerOptionsInfo gameControllerOptionInfo = getControllerOptionsList().at(currentListsIndex); gameControllerOptionInfo.setProfileLocation(""); gameControllerOptionInfo.setUnloadRequest(true); controllerOptionsList.replace(currentListsIndex, gameControllerOptionInfo); QStringList parserVals = QStringList() << parser.values("unload"); QListIterator profileForUnload(parserVals); QString unloadedProfText = QString(); if (profileForUnload.hasNext()) { unloadedProfText = profileForUnload.next(); // A value has been passed. Attempt // to validate the value. bool validNumber = false; int tempNumber = unloadedProfText.toInt(&validNumber); if (validNumber) { controllerNumber = tempNumber; gameControllerOptionInfo = getControllerOptionsList().at(currentListsIndex); gameControllerOptionInfo.setControllerNumber(controllerNumber); controllerOptionsList.replace(currentListsIndex, gameControllerOptionInfo); } else if (!unloadedProfText.isEmpty()) { controllerIDString = unloadedProfText; gameControllerOptionInfo = getControllerOptionsList().at(currentListsIndex); gameControllerOptionInfo.setControllerID(controllerIDString); controllerOptionsList.replace(currentListsIndex, gameControllerOptionInfo); } else { throw std::runtime_error(QObject::tr("Controller identifier is not a valid value.").toStdString()); } } else { unloadProfile = true; profileLocation = ""; } } void CommandLineUtility::parseArgsStartSet(const QCommandLineParser &parser) { QStringList parserValues = QStringList() << parser.values("startSet"); QListIterator profileForStartset(parserValues); QString startSetText = QString(); if (profileForStartset.hasNext()) { startSetText = profileForStartset.next(); bool validNumber = false; int tempNumber = startSetText.toInt(&validNumber); if (validNumber && (tempNumber >= 1) && (tempNumber <= 8)) { startSetNumber = tempNumber; ControllerOptionsInfo tempInfo = getControllerOptionsList().at(currentListsIndex); tempInfo.setStartSetNumber(startSetNumber); controllerOptionsList.replace(currentListsIndex, tempInfo); } else if (validNumber) { throw std::runtime_error(QObject::tr("An invalid set number '%1' was specified.").arg(tempNumber).toStdString()); } if (profileForStartset.hasNext()) { startSetText = profileForStartset.next(); if (validNumber) { controllerNumber = tempNumber; ControllerOptionsInfo tempInfo = getControllerOptionsList().at(currentListsIndex); tempInfo.setControllerNumber(controllerNumber); controllerOptionsList.replace(currentListsIndex, tempInfo); } else if (!startSetText.isEmpty()) { controllerIDString = startSetText; ControllerOptionsInfo tempInfo = getControllerOptionsList().at(currentListsIndex); tempInfo.setControllerID(controllerIDString); controllerOptionsList.replace(currentListsIndex, tempInfo); } else { throw std::runtime_error( QObject::tr("Controller identifier '%s'' is not a valid value.").arg(startSetText).toStdString()); } } } else { throw std::runtime_error(QObject::tr("No set number was specified.").toStdString()); } } bool CommandLineUtility::isLaunchInTrayEnabled() { return launchInTray; } bool CommandLineUtility::isTrayHidden() { return hideTrayIcon; } bool CommandLineUtility::hasProfile() { return !profileLocation.isEmpty(); } bool CommandLineUtility::hasControllerNumber() { return (controllerNumber > 0); } QString CommandLineUtility::getProfileLocation() { return profileLocation; } int CommandLineUtility::getControllerNumber() { return controllerNumber; } bool CommandLineUtility::isHiddenRequested() { return hiddenRequest; } bool CommandLineUtility::isShowRequested() { return showRequest; } bool CommandLineUtility::hasControllerID() { return !controllerIDString.isEmpty(); } QString CommandLineUtility::getControllerID() { return controllerIDString; } bool CommandLineUtility::isUnloadRequested() { return unloadProfile; } int CommandLineUtility::getStartSetNumber() { return startSetNumber; } int CommandLineUtility::getJoyStartSetNumber() { return startSetNumber - 1; } bool CommandLineUtility::shouldListControllers() { return listControllers; } QString CommandLineUtility::getEventGenerator() { return eventGenerator; } Logger::LogLevel CommandLineUtility::getCurrentLogLevel() { return currentLogLevel; } QString CommandLineUtility::getCurrentLogFile() { return currentLogFile; } QList const &CommandLineUtility::getControllerOptionsList() { return controllerOptionsList; } bool CommandLineUtility::hasProfileInOptions() { bool result = false; QListIterator iter(getControllerOptionsList()); while (iter.hasNext()) { ControllerOptionsInfo temp = iter.next(); if (temp.hasProfile()) { result = true; iter.toBack(); } } return result; } AntiMicroX-antimicrox-b300273/src/commandlineutility.h000066400000000000000000000101231471077622000230210ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2021 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef COMMANDLINEPARSER_H #define COMMANDLINEPARSER_H class QCommandLineParser; #include #include "logger.h" class ControllerOptionsInfo { public: ControllerOptionsInfo() { controllerNumber = 0; startSetNumber = 0; unloadProfile = false; } bool hasProfile() { return !profileLocation.isEmpty(); } QString getProfileLocation() { return profileLocation; } void setProfileLocation(QString location) { profileLocation = location; } bool hasControllerNumber() { return (controllerNumber > 0); } int getControllerNumber() { return controllerNumber; } void setControllerNumber(int temp) { controllerNumber = temp; } bool hasControllerID() { return !controllerIDString.isEmpty(); } QString getControllerID() { return controllerIDString; } void setControllerID(QString temp) { controllerIDString = temp; } bool isUnloadRequested() { return unloadProfile; } void setUnloadRequest(bool status) { unloadProfile = status; } int getStartSetNumber() { return startSetNumber; } int getJoyStartSetNumber() { return startSetNumber - 1; } void setStartSetNumber(int temp) { if ((temp >= 1) && (temp <= 8)) { startSetNumber = temp; } } private: QString profileLocation; int controllerNumber; QString controllerIDString; int startSetNumber; bool unloadProfile; }; class CommandLineUtility : public QObject { Q_OBJECT public: explicit CommandLineUtility(QObject *parent = nullptr); /** * @brief load and parse arguments from commandline * * @param parsed_app * @exception std::runtime_error - in case of problems with parsing like unknown flag, wrong value etc */ void parseArguments(const QApplication &parsed_app); bool isLaunchInTrayEnabled(); bool isTrayHidden(); bool hasProfile(); bool hasControllerNumber(); bool hasControllerID(); bool isHiddenRequested(); bool isShowRequested(); bool isUnloadRequested(); bool shouldListControllers(); bool hasProfileInOptions(); int getControllerNumber(); int getStartSetNumber(); int getJoyStartSetNumber(); QString getControllerID(); QString getProfileLocation(); QString getEventGenerator(); QString getCurrentLogFile(); QList *getJoyStartSetNumberList(); QList const &getControllerOptionsList(); Logger::LogLevel getCurrentLogLevel(); protected: private: bool launchInTray; bool hideTrayIcon; bool hiddenRequest; bool showRequest; bool unloadProfile; bool listControllers; int startSetNumber; int controllerNumber; int currentListsIndex; QString profileLocation; QString controllerIDString; QString eventGenerator; QString currentLogFile; Logger::LogLevel currentLogLevel; QList controllerOptionsList; static QStringList eventGeneratorsList; void parseArgsProfile(const QCommandLineParser &parser); void parseArgsPrControle(const QCommandLineParser &parser); void parseArgsUnload(const QCommandLineParser &parser); void parseArgsStartSet(const QCommandLineParser &parser); }; #endif // COMMANDLINEPARSER_H AntiMicroX-antimicrox-b300273/src/common.cpp000066400000000000000000000161361471077622000207440ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "common.h" #include #include #include #include #include #include #ifdef Q_OS_WIN #include #endif namespace PadderCommon { QString preferredProfileDir(AntiMicroSettings *settings) { QString lastProfileDir = settings->value("LastProfileDir", "").toString(); QString defaultProfileDir = settings->value("DefaultProfileDir", "").toString(); QString lookupDir = QString(); if (!defaultProfileDir.isEmpty()) { QFileInfo dirinfo(defaultProfileDir); if (dirinfo.isDir() && dirinfo.isReadable()) lookupDir = defaultProfileDir; } if (lookupDir.isEmpty() && !lastProfileDir.isEmpty()) { QFileInfo dirinfo(lastProfileDir); if (dirinfo.isDir() && dirinfo.isReadable()) lookupDir = lastProfileDir; } if (lookupDir.isEmpty()) { #ifdef Q_OS_WIN #ifdef WIN_PORTABLE_PACKAGE QString portableProDir = QDir::currentPath().append("/profiles"); QFileInfo portableProDirInfo(portableProDir); if (portableProDirInfo.isDir() && portableProDirInfo.isReadable()) { lookupDir = portableProDir; } else { lookupDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); } #else lookupDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); #endif #else lookupDir = QDir::homePath(); #endif } return lookupDir; } QStringList arguments(const int &argc, char **argv) { QStringList list = QStringList(); for (int a = 0; a < argc; ++a) list << QString::fromLocal8Bit(argv[a]); return list; } QStringList parseArgumentsString(QString tempString) { bool inside = (!tempString.isEmpty() && tempString.at(0) == QChar('"')); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) QStringList tempList = tempString.split(QRegularExpression("\""), Qt::SkipEmptyParts); #else QStringList tempList = tempString.split(QRegularExpression("\""), QString::SkipEmptyParts); #endif QStringList finalList = QStringList(); QStringListIterator iter(tempList); while (iter.hasNext()) { QString temp = iter.next(); if (inside) finalList.append(temp); else #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) finalList.append(temp.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts)); #else finalList.append(temp.split(QRegularExpression("\\s+"), QString::SkipEmptyParts)); #endif inside = !inside; } return finalList; } /** * @brief Reload main application and base Qt translation files. * @param Based Qt translator * @param Application translator * @param Language code */ void reloadTranslations(QTranslator *translator, QTranslator *appTranslator, QString language) { // Remove application specific translation strings qApp->removeTranslator(translator); // Remove old Qt translation strings qApp->removeTranslator(appTranslator); // Load new Qt translation strings #if defined(Q_OS_UNIX) translator->load(QString("qt_").append(language), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); #elif defined(Q_OS_WIN) #ifdef QT_DEBUG translator->load(QString("qt_").append(language), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); #else translator->load(QString("qt_").append(language), QApplication::applicationDirPath().append("\\share\\qt\\translations")); #endif #endif qApp->installTranslator(appTranslator); // Load application specific translation strings #if defined(Q_OS_UNIX) translator->load("antimicrox_" + language, QApplication::applicationDirPath().append("/../share/antimicrox/translations")); #elif defined(Q_OS_WIN) translator->load("antimicrox_" + language, QApplication::applicationDirPath().append("\\share\\antimicrox\\translations")); #endif qApp->installTranslator(translator); } void lockInputDevices() { sdlWaitMutex.lock(); } void unlockInputDevices() { sdlWaitMutex.unlock(); } QIcon loadIcon(const QString &name, const QString &fallback_location) { qDebug() << " Application theme has icon named: " << name << " " << QIcon::hasThemeIcon(name); QFileInfo f(fallback_location); if (!f.exists()) { qWarning() << "file " << fallback_location << " does not exist!"; } return QIcon::fromTheme(name, QIcon(fallback_location)); } QIcon loadIcon(QString name) { bool has_icon = QIcon::hasThemeIcon(name); qDebug() << " Application theme has icon named: " << name << " " << has_icon; if (has_icon) return QIcon::fromTheme(name); QDirIterator it(":images/", QDirIterator::Subdirectories); QString fallback_location = ""; // search also for variants with underscore like document_save.png for document-save QRegularExpression regex = QRegularExpression(".*" + name.replace(QChar('-'), "[_-]") + "\\.(svg|png)"); while (it.hasNext()) { QString value = it.next(); if (value.contains(regex)) { fallback_location = value; qDebug() << "Found fallback icon: " << value << " for name: " << name << "and regex: " << regex; break; } } QFileInfo f(fallback_location); if (!f.exists()) { qWarning() << "file: " << fallback_location << " does not exist!"; } return QIcon::fromTheme(name, QIcon(fallback_location)); } void log_system_config() { VERBOSE() << "AntiMicroX version: " << PadderCommon::programVersion #ifdef ANTIMICROX_PKG_VERSION << " Package: " << ANTIMICROX_PKG_VERSION #endif #ifdef QT_DEBUG << " Type: Debug" #else << " Type: Release" #endif ; VERBOSE() << "SDL version: " << PadderCommon::sdlVersionUsed << " (Compiled with: " << PadderCommon::sdlVersionCompiled << ")"; VERBOSE() << QString("Host OS: %1 Version: %2 Architecture: %3") .arg(QSysInfo::productType(), QSysInfo::productVersion(), QSysInfo::currentCpuArchitecture()); } QWaitCondition waitThisOut; QMutex sdlWaitMutex; QMutex inputDaemonMutex; bool editingBindings = false; MouseHelper mouseHelperObj; } // namespace PadderCommon AntiMicroX-antimicrox-b300273/src/common.h000066400000000000000000000145131471077622000204060ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef COMMON_H #define COMMON_H #include "antimicrosettings.h" #include "config.h" #include "mousehelper.h" #include #include #include #include #include #include #ifdef Q_OS_WIN static QString findWinSystemConfigPath() { QString temp; temp = (!qgetenv("LocalAppData").isEmpty()) ? QString::fromUtf8(qgetenv("LocalAppData")) + "\\antimicrox" : QDir::homePath() + "\\.antimicrox"; return temp; } static QString findWinLocalConfigPath() { QString temp = QCoreApplication::applicationDirPath(); return temp; } static QString findWinDefaultConfigPath() { QString temp = findWinLocalConfigPath(); QFileInfo dirInfo(temp); if (!dirInfo.isWritable()) { temp = findWinSystemConfigPath(); } return temp; } #endif namespace PadderCommon { inline QString configPath() { #if defined(Q_OS_WIN) && defined(WIN_PORTABLE_PACKAGE) return findWinLocalConfigPath(); #elif defined(Q_OS_WIN) return findWinSystemConfigPath(); #else return (!qgetenv("XDG_CONFIG_HOME").isEmpty()) ? QString::fromUtf8(qgetenv("XDG_CONFIG_HOME")) + "/antimicrox" : QDir::homePath() + "/.config/antimicrox"; #endif } const QString configFileName = "antimicrox_settings.ini"; inline QString configFilePath() { #if defined(Q_OS_WIN) && defined(WIN_PORTABLE_PACKAGE) return QString(configPath()).append("\\").append(configFileName); #elif defined(Q_OS_WIN) return QString(configPath()).append("\\").append(configFileName); #else return QString(configPath()).append("/").append(configFileName); #endif } inline QString configLegacyFilePath() { #if defined(Q_OS_WIN) return ""; // earlier vesrions of antimicrox was not supported by Windows #else QString configPath = (!qgetenv("XDG_CONFIG_HOME").isEmpty()) ? QString::fromUtf8(qgetenv("XDG_CONFIG_HOME")) + "/antimicroX" : QDir::homePath() + "/.config/antimicroX"; return QString(configPath).append("/").append("antimicroX_settings.ini"); #endif } inline QString configAntimicroLegacyFilePath() { #if defined(Q_OS_WIN) QString temp = configFilePath().replace("antimicrox", "antimicro").replace("/", "\\"); return temp; #else QString configPath = (!qgetenv("XDG_CONFIG_HOME").isEmpty()) ? QString::fromUtf8(qgetenv("XDG_CONFIG_HOME")) + "/antimicro" : QDir::homePath() + "/.config/antimicro"; return QString(configPath).append("/").append("antimicro_settings.ini"); #endif } const int LATESTCONFIGFILEVERSION = 19; // Specify the last known profile version that requires a migration // to be performed in order to be compatible with the latest version. const int LATESTCONFIGMIGRATIONVERSION = 5; const QString localSocketKey = "antimicroxSignalListener"; const QString unhideCommand = "unhideWindow"; const QString githubProjectPage = "https://github.com/AntiMicroX/antimicrox/"; const QString githubIssuesPage = "https://github.com/AntiMicroX/antimicrox/issues"; const QString wikiPage = QString("%1/wiki").arg(githubProjectPage); const QString mouseDeviceName("antimicrox Mouse Emulation"); const QString keyboardDeviceName("antimicrox Keyboard Emulation"); const QString springMouseDeviceName("antimicrox Abs Mouse Emulation"); const int ANTIMICROX_MAJOR_VERSION = PROJECT_MAJOR_VERSION; const int ANTIMICROX_MINOR_VERSION = PROJECT_MINOR_VERSION; const int ANTIMICROX_PATCH_VERSION = PROJECT_PATCH_VERSION; const QString programVersion = QString("%1.%2.%3").arg(ANTIMICROX_MAJOR_VERSION).arg(ANTIMICROX_MINOR_VERSION).arg(ANTIMICROX_PATCH_VERSION) #ifdef QT_DEBUG + "-d" #endif ; const QString sdlVersionUsed = ([] { SDL_version linkedver; SDL_GetVersion(&linkedver); return QString("%1.%2.%3").arg(linkedver.major).arg(linkedver.minor).arg(linkedver.patch); })(); const QString sdlVersionCompiled = ([] { SDL_version compver; SDL_VERSION(&compver); return QString("%1.%2.%3").arg(compver.major).arg(compver.minor).arg(compver.patch); })(); extern QWaitCondition waitThisOut; extern QMutex sdlWaitMutex; extern QMutex inputDaemonMutex; extern bool editingBindings; extern MouseHelper mouseHelperObj; QString preferredProfileDir(AntiMicroSettings *settings); QStringList arguments(const int &argc, char **argv); QStringList parseArgumentsString(QString tempString); void reloadTranslations(QTranslator *translator, QTranslator *appTranslator, QString language); void lockInputDevices(); void unlockInputDevices(); /** * @brief Universal method for loading icons if current theme does not have this icon, then look for replacement in resources * * @param name - name of used icon like "document-open" according to spec * https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html * @return QIcon */ QIcon loadIcon(QString name); /** * @brief Universal method for loading icons * * @param name - name of used icon * @param fallback_location - location of icon loaded when icon described by name not found * @return QIcon */ QIcon loadIcon(const QString &name, const QString &fallback_location); /*! * \brief Returns the "human-readable" name of the given profile. */ inline QString getProfileName(QFileInfo &profile) { QString retVal = profile.completeBaseName(); return retVal; } void log_system_config(); } // namespace PadderCommon Q_DECLARE_METATYPE(QThread *) #endif // COMMON_H AntiMicroX-antimicrox-b300273/src/config.h.in000066400000000000000000000003431471077622000207640ustar00rootroot00000000000000 #ifndef CONFIG_H #define CONFIG_H #define PROJECT_MAJOR_VERSION @ANTIMICROX_MAJOR_VERSION@ #define PROJECT_MINOR_VERSION @ANTIMICROX_MINOR_VERSION@ #define PROJECT_PATCH_VERSION @ANTIMICROX_PATCH_VERSION@ #endif // CONFIG_H AntiMicroX-antimicrox-b300273/src/dpadcontextmenu.cpp000066400000000000000000000521761471077622000226620ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "dpadcontextmenu.h" #include "antkeymapper.h" #include "common.h" #include "inputdevice.h" #include "joydpad.h" #include "mousedialog/mousedpadsettingsdialog.h" #include #include #include DPadContextMenu::DPadContextMenu(JoyDPad *dpad, QWidget *parent) : QMenu(parent) , helper(dpad) { this->dpad = dpad; getHelper().moveToThread(dpad->thread()); connect(this, &DPadContextMenu::aboutToHide, this, &DPadContextMenu::deleteLater); } /** * @brief Generate the context menu that will be shown to a user when the person * right clicks on the DPad settings button. */ void DPadContextMenu::buildMenu() { QActionGroup *presetGroup = new QActionGroup(this); QAction *action = nullptr; int presetMode = 0; int currentPreset = getPresetIndex(); generateActionPreset(action, tr("Mouse (Normal)"), currentPreset, presetMode, presetGroup); generateActionPreset(action, tr("Mouse (Inverted Horizontal)"), currentPreset, presetMode, presetGroup); generateActionPreset(action, tr("Mouse (Inverted Vertical)"), currentPreset, presetMode, presetGroup); generateActionPreset(action, tr("Mouse (Inverted Horizontal + Vertical)"), currentPreset, presetMode, presetGroup); generateActionPreset(action, tr("Arrows"), currentPreset, presetMode, presetGroup); generateActionPreset(action, tr("Keys: W | A | S | D"), currentPreset, presetMode, presetGroup); generateActionPreset(action, tr("NumPad"), currentPreset, presetMode, presetGroup); generateActionPreset(action, tr("None"), currentPreset, presetMode, presetGroup); this->addSeparator(); QActionGroup *modesGroup = new QActionGroup(this); generateActionMode(modesGroup, action, tr("Standard"), static_cast(dpad->getJoyMode()), static_cast(JoyDPad::StandardMode)); generateActionMode(modesGroup, action, tr("Eight Way"), static_cast(dpad->getJoyMode()), static_cast(JoyDPad::EightWayMode)); generateActionMode(modesGroup, action, tr("4 Way Cardinal"), static_cast(dpad->getJoyMode()), static_cast(JoyDPad::FourWayCardinal)); generateActionMode(modesGroup, action, tr("4 Way Diagonal"), static_cast(dpad->getJoyMode()), static_cast(JoyDPad::FourWayDiagonal)); this->addSeparator(); action = this->addAction(tr("Mouse Settings")); action->setCheckable(false); connect(action, &QAction::triggered, this, &DPadContextMenu::openMouseSettingsDialog); } void DPadContextMenu::generateActionPreset(QAction *action, QString actionText, int currentPreset, int &presetMode, QActionGroup *presetGroup) { action = this->addAction(actionText); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action] { setDPadPreset(action); }); presetGroup->addAction(action); presetMode++; } void DPadContextMenu::generateActionMode(QActionGroup *modesGroup, QAction *action, QString actionText, int currentPreset, int presetMode) { action = this->addAction(actionText); action->setCheckable(true); action->setChecked(currentPreset == presetMode); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action] { setDPadMode(action); }); modesGroup->addAction(action); } /** * @brief Set the appropriate mode for a DPad based on the item chosen. */ void DPadContextMenu::setDPadMode(QAction *action) { int item = action->data().toInt(); dpad->setJoyMode(static_cast(item)); } /** * @brief Assign the appropriate slots to DPad buttons based on the preset item * that was chosen. */ void DPadContextMenu::setDPadPreset(QAction *action) { int item = action->data().toInt(); JoyButtonSlot *upButtonSlot = nullptr; JoyButtonSlot *downButtonSlot = nullptr; JoyButtonSlot *leftButtonSlot = nullptr; JoyButtonSlot *rightButtonSlot = nullptr; JoyButtonSlot *upLeftButtonSlot = nullptr; JoyButtonSlot *upRightButtonSlot = nullptr; JoyButtonSlot *downLeftButtonSlot = nullptr; JoyButtonSlot *downRightButtonSlot = nullptr; switch (item) { case 0: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); dpad->setJoyMode(JoyDPad::StandardMode); PadderCommon::inputDaemonMutex.unlock(); break; case 1: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); dpad->setJoyMode(JoyDPad::StandardMode); PadderCommon::inputDaemonMutex.unlock(); break; case 2: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); dpad->setJoyMode(JoyDPad::StandardMode); PadderCommon::inputDaemonMutex.unlock(); break; case 3: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); dpad->setJoyMode(JoyDPad::StandardMode); PadderCommon::inputDaemonMutex.unlock(); break; case 4: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up), Qt::Key_Up, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down), Qt::Key_Down, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left), Qt::Key_Left, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right), Qt::Key_Right, JoyButtonSlot::JoyKeyboard, this); dpad->setJoyMode(JoyDPad::StandardMode); PadderCommon::inputDaemonMutex.unlock(); break; case 5: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W), Qt::Key_W, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S), Qt::Key_S, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A), Qt::Key_A, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D), Qt::Key_D, JoyButtonSlot::JoyKeyboard, this); dpad->setJoyMode(JoyDPad::StandardMode); PadderCommon::inputDaemonMutex.unlock(); break; case 6: PadderCommon::inputDaemonMutex.lock(); if ((dpad->getJoyMode() == JoyDPad::StandardMode) || (dpad->getJoyMode() == JoyDPad::FourWayCardinal)) { upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); } else if (dpad->getJoyMode() == JoyDPad::EightWayMode) { upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); } else if (dpad->getJoyMode() == JoyDPad::FourWayDiagonal) { upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); } PadderCommon::inputDaemonMutex.unlock(); break; case 7: QMetaObject::invokeMethod(&helper, "clearButtonsSlotsEventReset", Qt::BlockingQueuedConnection); break; } QHash tempHash; tempHash.insert(JoyDPadButton::DpadUp, upButtonSlot); tempHash.insert(JoyDPadButton::DpadDown, downButtonSlot); tempHash.insert(JoyDPadButton::DpadLeft, leftButtonSlot); tempHash.insert(JoyDPadButton::DpadRight, rightButtonSlot); tempHash.insert(JoyDPadButton::DpadLeftUp, upLeftButtonSlot); tempHash.insert(JoyDPadButton::DpadRightUp, upRightButtonSlot); tempHash.insert(JoyDPadButton::DpadLeftDown, downLeftButtonSlot); tempHash.insert(JoyDPadButton::DpadRightDown, downRightButtonSlot); getHelper().setPendingSlots(&tempHash); QMetaObject::invokeMethod(&helper, "setFromPendingSlots", Qt::BlockingQueuedConnection); } /** * @brief Find the appropriate menu item index for the currently assigned * slots that are assigned to a DPad. * @return Menu index that corresponds to the currently assigned preset choice. * 0 means that no matching preset was found. */ int DPadContextMenu::getPresetIndex() { int result = 0; PadderCommon::inputDaemonMutex.lock(); JoyDPadButton *upButton = dpad->getJoyButton(JoyDPadButton::DpadUp); QList *upslots = upButton->getAssignedSlots(); JoyDPadButton *downButton = dpad->getJoyButton(JoyDPadButton::DpadDown); QList *downslots = downButton->getAssignedSlots(); JoyDPadButton *leftButton = dpad->getJoyButton(JoyDPadButton::DpadLeft); QList *leftslots = leftButton->getAssignedSlots(); JoyDPadButton *rightButton = dpad->getJoyButton(JoyDPadButton::DpadRight); QList *rightslots = rightButton->getAssignedSlots(); if ((upslots->length() == 1) && (downslots->length() == 1) && (leftslots->length() == 1) && (rightslots->length() == 1)) { JoyButtonSlot *upslot = upslots->at(0); JoyButtonSlot *downslot = downslots->at(0); JoyButtonSlot *leftslot = leftslots->at(0); JoyButtonSlot *rightslot = rightslots->at(0); if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseUp) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseDown) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseRight)) { result = 1; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseUp) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseDown) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseRight) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { result = 2; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseDown) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseUp) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseRight)) { result = 3; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseDown) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseUp) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseRight) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { result = 4; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right))) { result = 5; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D))) { result = 6; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6))) { result = 7; } } else if ((upslots->length() == 0) && (downslots->length() == 0) && (leftslots->length() == 0) && (rightslots->length() == 0)) { result = 8; } PadderCommon::inputDaemonMutex.unlock(); return result; } /** * @brief Open a mouse settings dialog for changing the mouse speed settings * for all DPad buttons. */ void DPadContextMenu::openMouseSettingsDialog() { MouseDPadSettingsDialog *dialog = new MouseDPadSettingsDialog(dpad, parentWidget()); dialog->show(); } DPadContextMenuHelper &DPadContextMenu::getHelper() { return helper; } AntiMicroX-antimicrox-b300273/src/dpadcontextmenu.h000066400000000000000000000033621471077622000223200ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DPADCONTEXTMENU_H #define DPADCONTEXTMENU_H #include "uihelpers/dpadcontextmenuhelper.h" #include #include class JoyDPad; class QWidget; class DPadContextMenu : public QMenu { Q_OBJECT public: explicit DPadContextMenu(JoyDPad *dpad, QWidget *parent = nullptr); void buildMenu(); protected: int getPresetIndex(); private slots: void setDPadPreset(QAction *action); void setDPadMode(QAction *action); void openMouseSettingsDialog(); private: DPadContextMenuHelper &getHelper(); JoyDPad *dpad; DPadContextMenuHelper helper; void generateActionPreset(QAction *action, QString actionText, int currentPreset, int &presetMode, QActionGroup *presetGroup); void generateActionMode(QActionGroup *modesGroup, QAction *action, QString actionText, int currentPreset, int presetMode); }; #endif // DPADCONTEXTMENU_H AntiMicroX-antimicrox-b300273/src/dpadpushbutton.cpp000066400000000000000000000050031471077622000225070ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "dpadpushbutton.h" #include "dpadcontextmenu.h" #include "joydpad.h" #include DPadPushButton::DPadPushButton(JoyDPad *dpad, bool displayNames, QWidget *parent) : FlashButtonWidget(displayNames, parent) { this->dpad = dpad; refreshLabel(); enableFlashes(); tryFlash(); this->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &DPadPushButton::customContextMenuRequested, this, &DPadPushButton::showContextMenu); connect(dpad, &JoyDPad::dpadNameChanged, this, &DPadPushButton::refreshLabel); } JoyDPad *DPadPushButton::getDPad() const { return dpad; } QString DPadPushButton::generateLabel() { QString temp = QString(); if (!dpad->getDpadName().isEmpty()) temp.append(dpad->getName(false, ifDisplayNames())); else temp.append(dpad->getName()); qDebug() << "Dpad button name is: " << temp; return temp; } void DPadPushButton::disableFlashes() { disconnect(dpad, &JoyDPad::active, this, &DPadPushButton::flash); disconnect(dpad, &JoyDPad::released, this, &DPadPushButton::unflash); this->unflash(); } void DPadPushButton::enableFlashes() { connect(dpad, &JoyDPad::active, this, &DPadPushButton::flash, Qt::QueuedConnection); connect(dpad, &JoyDPad::released, this, &DPadPushButton::unflash, Qt::QueuedConnection); } void DPadPushButton::showContextMenu(const QPoint &point) { QPoint globalPos = this->mapToGlobal(point); DPadContextMenu *contextMenu = new DPadContextMenu(dpad, this); contextMenu->buildMenu(); contextMenu->popup(globalPos); } void DPadPushButton::tryFlash() { if (dpad->getCurrentDirection() != static_cast(JoyDPadButton::DpadCentered)) { flash(); } } AntiMicroX-antimicrox-b300273/src/dpadpushbutton.h000066400000000000000000000026111471077622000221560ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DPADPUSHBUTTON_H #define DPADPUSHBUTTON_H #include "flashbuttonwidget.h" class JoyDPad; class QWidget; class DPadPushButton : public FlashButtonWidget { Q_OBJECT public: explicit DPadPushButton(JoyDPad *dpad, bool displayNames, QWidget *parent = nullptr); JoyDPad *getDPad() const; void tryFlash(); protected: QString generateLabel() override; public slots: void disableFlashes() override; void enableFlashes() override; private slots: void showContextMenu(const QPoint &point); private: JoyDPad *dpad; }; #endif // DPADPUSHBUTTON_H AntiMicroX-antimicrox-b300273/src/dpadpushbuttongroup.cpp000066400000000000000000000121111471077622000235620ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "dpadpushbuttongroup.h" #include "buttoneditdialog.h" #include "dpadeditdialog.h" #include "dpadpushbutton.h" #include "inputdevice.h" #include "joydpad.h" #include "joydpadbuttonwidget.h" #include #include #include DPadPushButtonGroup::DPadPushButtonGroup(JoyDPad *dpad, bool keypadUnlocked, bool displayNames, QWidget *parent) : QGridLayout(parent) { this->dpad = dpad; this->displayNames = displayNames; this->keypadUnlocked = keypadUnlocked; generateButtons(); changeButtonLayout(); connect(dpad, &JoyDPad::joyModeChanged, this, &DPadPushButtonGroup::changeButtonLayout); } void DPadPushButtonGroup::generateButtons() { QHash *buttons = dpad->getJoyButtons(); upLeftButton = generateBtnForGrid(buttons, 9, 0, 0); upButton = generateBtnForGrid(buttons, 1, 0, 1); upRightButton = generateBtnForGrid(buttons, 3, 0, 2); leftButton = generateBtnForGrid(buttons, 8, 1, 0); dpadWidget = new DPadPushButton(dpad, displayNames, parentWidget()); dpadWidget->setIcon( QIcon::fromTheme(QString::fromUtf8("games_config_options"), QIcon(":/images/actions/games_config_options.png"))); connect(dpadWidget, &DPadPushButton::clicked, this, &DPadPushButtonGroup::showDPadDialog); addWidget(dpadWidget, 1, 1); rightButton = generateBtnForGrid(buttons, 2, 1, 2); downLeftButton = generateBtnForGrid(buttons, 12, 2, 0); downButton = generateBtnForGrid(buttons, 4, 2, 1); downRightButton = generateBtnForGrid(buttons, 6, 2, 2); } JoyDPadButtonWidget *DPadPushButtonGroup::generateBtnForGrid(QHash *buttons, int dpadDirection, int cellRow, int cellCol) { JoyDPadButton *button = buttons->value(static_cast(dpadDirection)); JoyDPadButtonWidget *pushbutton = new JoyDPadButtonWidget(button, displayNames, parentWidget()); connect(pushbutton, &JoyDPadButtonWidget::clicked, this, [this, pushbutton] { openDPadButtonDialog(pushbutton); }); button->establishPropertyUpdatedConnections(); connect(button, &JoyDPadButton::slotsChanged, this, &DPadPushButtonGroup::propogateSlotsChanged); addWidget(pushbutton, cellRow, cellCol); return pushbutton; } void DPadPushButtonGroup::changeButtonLayout() { if ((dpad->getJoyMode() == JoyDPad::StandardMode) || (dpad->getJoyMode() == JoyDPad::EightWayMode) || (dpad->getJoyMode() == JoyDPad::FourWayCardinal)) { upButton->setVisible(true); downButton->setVisible(true); leftButton->setVisible(true); rightButton->setVisible(true); } else { upButton->setVisible(false); downButton->setVisible(false); leftButton->setVisible(false); rightButton->setVisible(false); } if ((dpad->getJoyMode() == JoyDPad::EightWayMode) || (dpad->getJoyMode() == JoyDPad::FourWayDiagonal)) { upLeftButton->setVisible(true); upRightButton->setVisible(true); downLeftButton->setVisible(true); downRightButton->setVisible(true); } else { upLeftButton->setVisible(false); upRightButton->setVisible(false); downLeftButton->setVisible(false); downRightButton->setVisible(false); } } void DPadPushButtonGroup::propogateSlotsChanged() { emit buttonSlotChanged(); } JoyDPad *DPadPushButtonGroup::getDPad() const { return dpad; } void DPadPushButtonGroup::openDPadButtonDialog(JoyButtonWidget *buttonWidget) { JoyButton *button = buttonWidget->getJoyButton(); ButtonEditDialog *dialog = new ButtonEditDialog(button, dpad->getParentSet()->getInputDevice(), keypadUnlocked, parentWidget()); dialog->show(); } void DPadPushButtonGroup::showDPadDialog() { DPadEditDialog *dialog = new DPadEditDialog(dpad, parentWidget()); dialog->show(); } void DPadPushButtonGroup::toggleNameDisplay() { displayNames = !displayNames; upButton->toggleNameDisplay(); downButton->toggleNameDisplay(); leftButton->toggleNameDisplay(); rightButton->toggleNameDisplay(); upLeftButton->toggleNameDisplay(); upRightButton->toggleNameDisplay(); downLeftButton->toggleNameDisplay(); downRightButton->toggleNameDisplay(); dpadWidget->toggleNameDisplay(); } AntiMicroX-antimicrox-b300273/src/dpadpushbuttongroup.h000066400000000000000000000042201471077622000232310ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DPADPUSHBUTTONGROUP_H #define DPADPUSHBUTTONGROUP_H #include class JoyDPad; class QWidget; class JoyDPadButtonWidget; class DPadPushButton; class JoyButtonWidget; class JoyDPadButton; class DPadPushButtonGroup : public QGridLayout { Q_OBJECT public: explicit DPadPushButtonGroup(JoyDPad *dpad, bool keypadUnlocked, bool displayNames = false, QWidget *parent = nullptr); JoyDPad *getDPad() const; protected: void generateButtons(); signals: void buttonSlotChanged(); public slots: void changeButtonLayout(); void toggleNameDisplay(); private slots: void propogateSlotsChanged(); void openDPadButtonDialog(JoyButtonWidget *buttonWidget); void showDPadDialog(); private: JoyDPad *dpad; bool keypadUnlocked; bool displayNames; JoyDPadButtonWidget *upButton; JoyDPadButtonWidget *downButton; JoyDPadButtonWidget *leftButton; JoyDPadButtonWidget *rightButton; JoyDPadButtonWidget *upLeftButton; JoyDPadButtonWidget *upRightButton; JoyDPadButtonWidget *downLeftButton; JoyDPadButtonWidget *downRightButton; DPadPushButton *dpadWidget; JoyDPadButtonWidget *generateBtnForGrid(QHash *buttons, int dpadDirection, int cellRow, int cellCol); }; #endif // DPADPUSHBUTTONGROUP_H AntiMicroX-antimicrox-b300273/src/event.cpp000066400000000000000000000700631471077622000205740ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2021 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include "event.h" #include "eventhandlerfactory.h" #include "globalvariables.h" #include "joybuttontypes/joybutton.h" #include "logger.h" #if defined(Q_OS_UNIX) #if defined(WITH_X11) #include "x11extras.h" #include #include #include #ifdef WITH_XTEST #include #endif #endif #if defined(WITH_UINPUT) #include "uinputhelper.h" #endif #elif defined(Q_OS_WIN) #include "winextras.h" #include #endif // TODO: Implement function for determining final mouse pointer position // based around a fixed bounding box resolution. void fakeAbsMouseCoordinates(double springX, double springY, int width, int height, int &finalx, int &finaly, int screen) { int screenWidth = 0; int screenHeight = 0; int screenMidwidth = 0; int screenMidheight = 0; int destSpringWidth = 0; int destSpringHeight = 0; int destMidWidth = 0; int destMidHeight = 0; QRect deskRect = QGuiApplication::screens().at(screen)->geometry(); screenWidth = deskRect.width(); screenHeight = deskRect.height(); screenMidwidth = screenWidth / 2; screenMidheight = screenHeight / 2; if ((width >= 2) && (height >= 2)) { destSpringWidth = qMin(width, screenWidth); destSpringHeight = qMin(height, screenHeight); } else { destSpringWidth = screenWidth; destSpringHeight = screenHeight; } destMidWidth = destSpringWidth / 2; destMidHeight = destSpringHeight / 2; finalx = (screenMidwidth + (springX * destMidWidth) + deskRect.x()); finaly = (screenMidheight + (springY * destMidHeight) + deskRect.y()); } /** * @brief detects executor for selected file (for .py files python, for .exe "" etc) */ QString detectedScriptExt(QString file) { QFileInfo fileinfo(file); QFile inputFile(file); QString firstLine = QString(); if (inputFile.open(QIODevice::ReadOnly)) { QTextStream in(&inputFile); firstLine = in.readLine(); inputFile.close(); } else WARN() << "Could not open file: " << file; /* * shell scripts work, but I am not sure about other extensions * neither start method form QProcess nor QProcess::startDetached * don't work as expected * need to find another way */ if (firstLine.contains("bin/bash")) return "/bin/sh"; else if (fileinfo.completeSuffix() == "py" && firstLine.contains("python3")) return "python3"; else if (fileinfo.completeSuffix() == "py" && firstLine.contains("python")) return "python"; else if (fileinfo.completeSuffix() == "pl" || firstLine.contains("usr/bin/perl")) return "perl"; else if (fileinfo.completeSuffix() == "php" || firstLine.contains("/php")) return "php"; else if (fileinfo.completeSuffix() == "rb" || firstLine.contains("ruby")) return "ruby"; // when run "chmod +x file_name" return ""; } // Create the event used by the operating system. void sendevent(JoyButtonSlot *slot, bool pressed) { JoyButtonSlot::JoySlotInputAction device = slot->getSlotMode(); if (device == JoyButtonSlot::JoyKeyboard) { EventHandlerFactory::getInstance()->handler()->sendKeyboardEvent(slot, pressed); } else if (device == JoyButtonSlot::JoyMouseButton) { EventHandlerFactory::getInstance()->handler()->sendMouseButtonEvent(slot, pressed); } else if ((device == JoyButtonSlot::JoyTextEntry) && pressed && !slot->getTextData().isEmpty()) { EventHandlerFactory::getInstance()->handler()->sendTextEntryEvent(slot->getTextData()); } else if ((device == JoyButtonSlot::JoyExecute) && pressed && !slot->getTextData().isEmpty()) { QStringList argumentsTempList = {}; QString argumentsString = slot->getExtraData().toString(); if (slot->getExtraData().canConvert()) { argumentsTempList = PadderCommon::parseArgumentsString(argumentsString); } qint64 pid = 0; QString process_executor = detectedScriptExt(slot->getTextData()); if (process_executor.isEmpty()) { process_executor = slot->getTextData(); } else { argumentsTempList.prepend(slot->getTextData()); } #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) QProcess process; process.setProgram(process_executor); process.setArguments(argumentsTempList); process.setWorkingDirectory(QFileInfo(slot->getTextData()).absoluteDir().path()); bool success = process.startDetached(&pid); #else bool success = QProcess::startDetached(process_executor, argumentsTempList, QFileInfo(slot->getTextData()).absoluteDir().path(), &pid); #endif if (success) qInfo() << "Command: " << slot->getTextData() << " " << argumentsString << " executed successfully with pid: " << pid; else qWarning() << "Command " << slot->getTextData() << " " << argumentsString << " cannot be executed, pid: " << pid; } } // Create the relative mouse event used by the operating system. void sendevent(int code1, int code2) { EventHandlerFactory::getInstance()->handler()->sendMouseEvent(code1, code2); } // TODO: Re-implement spring event generation to simplify the process // and reduce overhead. Refactor old function to only be used when an absmouse // position must be faked. void sendSpringEventRefactor(PadderCommon::springModeInfo *fullSpring, PadderCommon::springModeInfo *relativeSpring, int *const mousePosX, int *const mousePosY) { Q_UNUSED(relativeSpring) Q_UNUSED(mousePosX) Q_UNUSED(mousePosY) PadderCommon::mouseHelperObj.mouseTimer.stop(); if (fullSpring != nullptr) { int xmovecoor = 0; int ymovecoor = 0; double displacementX = 0.0; double displacementY = 0.0; PadderCommon::mouseHelperObj.mouseTimer.stop(); BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); if ((fullSpring->screen >= -1) && (fullSpring->screen >= QGuiApplication::screens().count())) { fullSpring->screen = -1; } int springWidth = fullSpring->width; int springHeight = fullSpring->height; if ((springWidth >= 2) && (springHeight >= 2)) { displacementX = fullSpring->displacementX; displacementY = fullSpring->displacementY; } else { displacementX = fullSpring->displacementX; displacementY = fullSpring->displacementY; } if (relativeSpring && (relativeSpring->width >= 2) && (relativeSpring->height >= 2)) { int pivotX = 0; int pivotY = 0; if (PadderCommon::mouseHelperObj.pivotPoint[0] != -1) pivotX = PadderCommon::mouseHelperObj.pivotPoint[0]; if (PadderCommon::mouseHelperObj.pivotPoint[1] != -1) pivotY = PadderCommon::mouseHelperObj.pivotPoint[1]; if ((pivotX >= 0) && (pivotY >= 0)) { // Find a use for this routine in this context. int destRelativeWidth = relativeSpring->width; int destRelativeHeight = relativeSpring->height; int xRelativeMoovCoor = 0; int yRelativeMoovCoor = 0; if (relativeSpring->displacementX >= -1.0) xRelativeMoovCoor = (relativeSpring->displacementX * destRelativeWidth) / 2; if (relativeSpring->displacementY >= -1.0) yRelativeMoovCoor = (relativeSpring->displacementY * destRelativeHeight) / 2; xmovecoor += xRelativeMoovCoor; ymovecoor += yRelativeMoovCoor; } } if (handler->getIdentifier() == "xtest") { fakeAbsMouseCoordinates(displacementX, displacementY, springWidth, springHeight, xmovecoor, ymovecoor, fullSpring->screen); } else if (handler->getIdentifier() == "uinput") { fakeAbsMouseCoordinates(displacementX, displacementY, springWidth, springHeight, xmovecoor, ymovecoor, fullSpring->screen); } } else { PadderCommon::mouseHelperObj.springMouseMoving = false; PadderCommon::mouseHelperObj.pivotPoint[0] = -1; PadderCommon::mouseHelperObj.pivotPoint[1] = -1; } } // TODO: Change to only use this routine when using a relative mouse // pointer to fake absolute mouse moves. Otherwise, don't worry about // current position of the mouse and just send an absolute mouse pointer // event. void sendSpringEvent(PadderCommon::springModeInfo *fullSpring, PadderCommon::springModeInfo *relativeSpring, int *const mousePosX, int *const mousePosY) { PadderCommon::mouseHelperObj.mouseTimer.stop(); if (((fullSpring->displacementX >= -2.0) && (fullSpring->displacementX <= 1.0) && (fullSpring->displacementY >= -2.0) && (fullSpring->displacementY <= 1.0)) || (relativeSpring && ((relativeSpring->displacementX >= -2.0) && (relativeSpring->displacementX <= 1.0) && (relativeSpring->displacementY >= -2.0) && (relativeSpring->displacementY <= 1.0)))) { int xmovecoor = 0; int ymovecoor = 0; int width = 0; int height = 0; int midwidth = 0; int midheight = 0; int destSpringWidth = 0; int destSpringHeight = 0; int destMidWidth = 0; int destMidHeight = 0; int currentMouseX = 0; int currentMouseY = 0; if ((fullSpring->screen >= -1) && (fullSpring->screen >= QGuiApplication::screens().count())) { fullSpring->screen = -1; } QRect deskRect = fullSpring->screen == -1 ? QGuiApplication::primaryScreen()->geometry() : QGuiApplication::screens().at(fullSpring->screen)->geometry(); width = deskRect.width(); height = deskRect.height(); QPoint currentPoint; if (QApplication::platformName() == QStringLiteral("xcb")) { #if defined(WITH_X11) currentPoint = X11Extras::getInstance()->getPos(); #else qCritical() << "Platform name returned 'xcb', but X11 support is disabled"; #endif } else { currentPoint = QCursor::pos(); } currentMouseX = currentPoint.x(); currentMouseY = currentPoint.y(); midwidth = width / 2; midheight = height / 2; int springWidth = fullSpring->width; int springHeight = fullSpring->height; if ((springWidth >= 2) && (springHeight >= 2)) { destSpringWidth = qMin(springWidth, width); destSpringHeight = qMin(springHeight, height); } else { destSpringWidth = width; destSpringHeight = height; } destMidWidth = destSpringWidth / 2; destMidHeight = destSpringHeight / 2; int pivotX = currentMouseX; int pivotY = currentMouseY; if (relativeSpring != nullptr) { if (PadderCommon::mouseHelperObj.pivotPoint[0] != -1) { pivotX = PadderCommon::mouseHelperObj.pivotPoint[0]; } else { pivotX = currentMouseX; } if (PadderCommon::mouseHelperObj.pivotPoint[1] != -1) { pivotY = PadderCommon::mouseHelperObj.pivotPoint[1]; } else { pivotY = currentMouseY; } } xmovecoor = (fullSpring->displacementX >= -1.0) ? (midwidth + (fullSpring->displacementX * destMidWidth) + deskRect.x()) : pivotX; ymovecoor = (fullSpring->displacementY >= -1.0) ? (midheight + (fullSpring->displacementY * destMidHeight) + deskRect.y()) : pivotY; int fullSpringDestX = xmovecoor; int fullSpringDestY = ymovecoor; int destRelativeWidth = 0; int destRelativeHeight = 0; if ((relativeSpring != nullptr) && (relativeSpring->width >= 2) && (relativeSpring->height >= 2)) { destRelativeWidth = relativeSpring->width; destRelativeHeight = relativeSpring->height; int xRelativeMoovCoor = 0; int yRelativeMoovCoor = 0; if (relativeSpring->displacementX >= -1.0) xRelativeMoovCoor = (relativeSpring->displacementX * destRelativeWidth) / 2; if (relativeSpring->displacementY >= -1.0) yRelativeMoovCoor = (relativeSpring->displacementY * destRelativeHeight) / 2; xmovecoor += xRelativeMoovCoor; ymovecoor += yRelativeMoovCoor; } if (mousePosX) *mousePosX = xmovecoor; if (mousePosY) *mousePosY = ymovecoor; if ((xmovecoor != currentMouseX) || (ymovecoor != currentMouseY)) { double diffx = abs(currentMouseX - xmovecoor); double diffy = abs(currentMouseY - ymovecoor); // If either position is set to center, force update. if ((xmovecoor == (deskRect.x() + midwidth)) || (ymovecoor == (deskRect.y() + midheight))) { #if defined(Q_OS_UNIX) BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); if (fullSpring->screen <= -1) { if (handler->getIdentifier() == "xtest") { EventHandlerFactory::getInstance()->handler()->sendMouseAbsEvent(xmovecoor, ymovecoor, -1); } else if (handler->getIdentifier() == "uinput") { EventHandlerFactory::getInstance()->handler()->sendMouseSpringEvent( xmovecoor, ymovecoor, width + deskRect.x(), height + deskRect.y()); } } else { EventHandlerFactory::getInstance()->handler()->sendMouseEvent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); } #elif defined(Q_OS_WIN) if (fullSpring->screen <= -1) { EventHandlerFactory::getInstance()->handler()->sendMouseSpringEvent( xmovecoor, ymovecoor, width + deskRect.x(), height + deskRect.y()); } else { sendevent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); } #endif } else if (!PadderCommon::mouseHelperObj.springMouseMoving && relativeSpring && ((relativeSpring->displacementX >= -1.0) || (relativeSpring->displacementY >= -1.0)) && ((diffx >= (destRelativeWidth * .013)) || (diffy >= (destRelativeHeight * .013)))) { PadderCommon::mouseHelperObj.springMouseMoving = true; #if defined(Q_OS_UNIX) BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); if (fullSpring->screen <= -1) { if (handler->getIdentifier() == "xtest") { EventHandlerFactory::getInstance()->handler()->sendMouseAbsEvent(xmovecoor, ymovecoor, -1); } else if (handler->getIdentifier() == "uinput") { EventHandlerFactory::getInstance()->handler()->sendMouseSpringEvent( xmovecoor, ymovecoor, width + deskRect.x(), height + deskRect.y()); } } else { EventHandlerFactory::getInstance()->handler()->sendMouseEvent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); } #elif defined(Q_OS_WIN) if (fullSpring->screen <= -1) { EventHandlerFactory::getInstance()->handler()->sendMouseSpringEvent( xmovecoor, ymovecoor, width + deskRect.x(), height + deskRect.y()); } else { sendevent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); } #endif PadderCommon::mouseHelperObj.mouseTimer.start( qMax(GlobalVariables::JoyButton::mouseRefreshRate, GlobalVariables::JoyButton::gamepadRefreshRate) + 1); } else if (!PadderCommon::mouseHelperObj.springMouseMoving && ((diffx >= (destSpringWidth * .013)) || (diffy >= (destSpringHeight * .013)))) { PadderCommon::mouseHelperObj.springMouseMoving = true; #if defined(Q_OS_UNIX) BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); if (fullSpring->screen <= -1) { if (handler->getIdentifier() == "xtest") { EventHandlerFactory::getInstance()->handler()->sendMouseAbsEvent(xmovecoor, ymovecoor, -1); } else if (handler->getIdentifier() == "uinput") { EventHandlerFactory::getInstance()->handler()->sendMouseSpringEvent( xmovecoor, ymovecoor, width + deskRect.x(), height + deskRect.y()); } } else { EventHandlerFactory::getInstance()->handler()->sendMouseEvent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); } #elif defined(Q_OS_WIN) if (fullSpring->screen <= -1) { EventHandlerFactory::getInstance()->handler()->sendMouseSpringEvent( xmovecoor, ymovecoor, width + deskRect.x(), height + deskRect.y()); } else { sendevent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); } #endif PadderCommon::mouseHelperObj.mouseTimer.start( qMax(GlobalVariables::JoyButton::mouseRefreshRate, GlobalVariables::JoyButton::gamepadRefreshRate) + 1); } else if (PadderCommon::mouseHelperObj.springMouseMoving && ((diffx < 2) && (diffy < 2))) { PadderCommon::mouseHelperObj.springMouseMoving = false; } else if (PadderCommon::mouseHelperObj.springMouseMoving) { #if defined(Q_OS_UNIX) BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); if (fullSpring->screen <= -1) { if (handler->getIdentifier() == "xtest") { EventHandlerFactory::getInstance()->handler()->sendMouseAbsEvent(xmovecoor, ymovecoor, -1); } else if (handler->getIdentifier() == "uinput") { EventHandlerFactory::getInstance()->handler()->sendMouseSpringEvent( xmovecoor, ymovecoor, width + deskRect.x(), height + deskRect.y()); } } else { EventHandlerFactory::getInstance()->handler()->sendMouseEvent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); } #elif defined(Q_OS_WIN) if (fullSpring->screen <= -1) { EventHandlerFactory::getInstance()->handler()->sendMouseSpringEvent( xmovecoor, ymovecoor, width + deskRect.x(), height + deskRect.y()); } else { sendevent(xmovecoor - currentMouseX, ymovecoor - currentMouseY); } #endif PadderCommon::mouseHelperObj.mouseTimer.start( qMax(GlobalVariables::JoyButton::mouseRefreshRate, GlobalVariables::JoyButton::gamepadRefreshRate) + 1); } PadderCommon::mouseHelperObj.previousCursorLocation[0] = currentMouseX; PadderCommon::mouseHelperObj.previousCursorLocation[1] = currentMouseY; PadderCommon::mouseHelperObj.pivotPoint[0] = fullSpringDestX; PadderCommon::mouseHelperObj.pivotPoint[1] = fullSpringDestY; } else if ((PadderCommon::mouseHelperObj.previousCursorLocation[0] == xmovecoor) && (PadderCommon::mouseHelperObj.previousCursorLocation[1] == ymovecoor)) { PadderCommon::mouseHelperObj.springMouseMoving = false; } else { PadderCommon::mouseHelperObj.previousCursorLocation[0] = currentMouseX; PadderCommon::mouseHelperObj.previousCursorLocation[1] = currentMouseY; PadderCommon::mouseHelperObj.pivotPoint[0] = fullSpringDestX; PadderCommon::mouseHelperObj.pivotPoint[1] = fullSpringDestY; PadderCommon::mouseHelperObj.mouseTimer.start( qMax(GlobalVariables::JoyButton::mouseRefreshRate, GlobalVariables::JoyButton::gamepadRefreshRate) + 1); } } else { PadderCommon::mouseHelperObj.springMouseMoving = false; PadderCommon::mouseHelperObj.pivotPoint[0] = -1; PadderCommon::mouseHelperObj.pivotPoint[1] = -1; } } int X11KeySymToKeycode(QString key) { int tempcode = 0; #if defined(Q_OS_UNIX) BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); if (key.length() > 0) { #ifdef WITH_XTEST if (handler->getIdentifier() == "xtest") { Display *display = X11Extras::getInstance()->display(); tempcode = XKeysymToKeycode(display, XStringToKeysym(key.toUtf8().data())); } #endif #ifdef WITH_UINPUT if (handler->getIdentifier() == "uinput") { tempcode = UInputHelper::getInstance()->getVirtualKey(key); } #endif } #elif defined(Q_OS_WIN) if (key.length() > 0) { tempcode = WinExtras::getVirtualKey(key); if (tempcode <= 0 && key.length() == 1) { // qDebug() << "KEY: " << key; // int oridnal = key.toUtf8().constData()[0]; int ordinal = QVariant(key.toUtf8().constData()[0]).toInt(); tempcode = VkKeyScan(ordinal); int modifiers = tempcode >> 8; tempcode = tempcode & 0xff; if ((modifiers & 1) != 0) tempcode |= VK_SHIFT; if ((modifiers & 2) != 0) tempcode |= VK_CONTROL; if ((modifiers & 4) != 0) tempcode |= VK_MENU; // tempcode = VkKeyScan(QVariant(key.constData()).toInt()); // tempcode = OemKeyScan(key.toUtf8().toInt()); // tempcode = OemKeyScan(ordinal); } } #endif return tempcode; } QString keycodeToKeyString(int keycode, int alias) { QString newkey = QString(); Q_UNUSED(alias) #if defined(Q_OS_UNIX) Q_UNUSED(alias); if (keycode <= 0) { newkey = "[NO KEY]"; } else { BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); #ifdef WITH_XTEST if (handler->getIdentifier() == "xtest") { Display *display = X11Extras::getInstance()->display(); newkey = QString("0x%1").arg(keycode, 0, 16); QString tempkey = XKeysymToString(XkbKeycodeToKeysym(display, static_cast(keycode), 0, 0)); QString tempalias = X11Extras::getInstance()->getDisplayString(tempkey); if (!tempalias.isEmpty()) { newkey = tempalias; } else { XKeyPressedEvent tempevent; tempevent.keycode = keycode; tempevent.type = KeyPress; tempevent.display = display; tempevent.state = 0; char tempstring[256]; memset(tempstring, 0, sizeof(tempstring)); int bitestoreturn = sizeof(tempstring) - 1; int numchars = XLookupString(&tempevent, tempstring, bitestoreturn, nullptr, nullptr); if (numchars > 0) { tempstring[numchars] = '\0'; newkey = QString::fromUtf8(tempstring); qDebug() << "NEWKEY:" << newkey; qDebug() << "NEWKEY LEGNTH:" << numchars; } else { newkey = tempkey; } } } #endif #ifdef WITH_UINPUT if (handler->getIdentifier() == "uinput") { QString tempalias = UInputHelper::getInstance()->getDisplayString(keycode); if (!tempalias.isEmpty()) newkey = tempalias; else newkey = QString("0x%1").arg(keycode, 0, 16); } #endif } #elif defined(Q_OS_WIN) wchar_t buffer[50] = {0}; QString tempalias = WinExtras::getDisplayString(keycode); if (!tempalias.isEmpty()) { newkey = tempalias; } else { int scancode = WinExtras::scancodeFromVirtualKey(keycode, alias); if (keycode >= VK_BROWSER_BACK && keycode <= VK_LAUNCH_APP2) { newkey.append(QString("0x%1").arg(keycode, 0, 16)); } else { int length = GetKeyNameTextW(scancode << 16, buffer, sizeof(buffer)); if (length > 0) { newkey = QString::fromWCharArray(buffer); } else { newkey.append(QString("0x%1").arg(keycode, 0, 16)); } } } #endif return newkey; } int X11KeyCodeToX11KeySym(int keycode) { #ifdef Q_OS_WIN Q_UNUSED(keycode); return 0; #else #ifdef WITH_X11 Display *display = X11Extras::getInstance()->display(); unsigned int tempcode = XkbKeycodeToKeysym(display, keycode, 0, 0); return tempcode; #else Q_UNUSED(keycode); return 0; #endif #endif } QString keysymToKeyString(int keysym, int alias) { QString newkey = QString(); #ifdef WITH_X11 Q_UNUSED(alias) BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); if (handler->getIdentifier() == "xtest") { Display *display = X11Extras::getInstance()->display(); int keycode = 0; if (keysym > 0) keycode = XKeysymToKeycode(display, static_cast(keysym)); newkey = keycodeToKeyString(keycode); } else if (handler->getIdentifier() == "uinput") { newkey = keycodeToKeyString(keysym); } #else newkey = keycodeToKeyString(keysym, alias); #endif return newkey; } void sendKeybEvent(JoyButtonSlot *slot, bool pressed) { EventHandlerFactory::getInstance()->handler()->sendKeyboardEvent(slot, pressed); } AntiMicroX-antimicrox-b300273/src/event.h000066400000000000000000000027161471077622000202410ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef EVENT_H #define EVENT_H #include "common.h" #include "joybuttonslot.h" #include "springmousemoveinfo.h" void sendevent(JoyButtonSlot *slot, bool pressed = true); void sendevent(int code1, int code2); void sendKeybEvent(JoyButtonSlot *slot, bool pressed = true); void sendSpringEvent(PadderCommon::springModeInfo *fullSpring, PadderCommon::springModeInfo *relativeSpring = 0, int *const mousePosX = 0, int *const mousePos = 0); int X11KeySymToKeycode(QString key); QString keycodeToKeyString(int keycode, int alias = 0); int X11KeyCodeToX11KeySym(int keycode); QString keysymToKeyString(int keysym, int alias = 0); #endif // EVENT_H AntiMicroX-antimicrox-b300273/src/eventhandlerfactory.cpp000066400000000000000000000100321471077622000235100ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "eventhandlerfactory.h" #include "logger.h" #include "eventhandlers/baseeventhandler.h" #include #include static QHash buildDisplayNames() { QHash temp; #ifdef Q_OS_WIN temp.insert("sendinput", "SendInput"); #ifdef WITH_VMULTI temp.insert("vmulti", "Vmulti"); #endif #else temp.insert("xtest", "Xtest"); temp.insert("uinput", "uinput"); #endif return temp; } QHash handlerDisplayNames = buildDisplayNames(); EventHandlerFactory *EventHandlerFactory::instance = nullptr; EventHandlerFactory::EventHandlerFactory(QString handler, QObject *parent) : QObject(parent) { #ifdef WITH_UINPUT if (handler == "uinput") eventHandler = new UInputEventHandler(this); #endif #ifdef WITH_XTEST if (handler == "xtest") eventHandler = new XTestEventHandler(this); #endif #if defined(Q_OS_WIN) if (handler == "sendinput") { eventHandler = new WinSendInputEventHandler(this); } #endif } EventHandlerFactory *EventHandlerFactory::getInstance(QString handler) { if (instance == nullptr) { QStringList temp = buildEventGeneratorList(); if (!handler.isEmpty() && temp.contains(handler)) instance = new EventHandlerFactory(handler); else instance = new EventHandlerFactory(fallBackIdentifier()); } return instance; } void EventHandlerFactory::deleteInstance() { if (instance != nullptr) { delete instance; instance = nullptr; } } BaseEventHandler *EventHandlerFactory::handler() { return eventHandler; } QString EventHandlerFactory::fallBackIdentifier() { #if defined(Q_OS_UNIX) static QString temp = "xtest"; static bool identifier_obtained = false; if (identifier_obtained) return temp; QString detected_xdg_session = qgetenv("XDG_SESSION_TYPE"); bool compiled_with_x11 = false; bool compiled_with_uinput = false; #if defined(WITH_XTEST) compiled_with_x11 = true; #endif #if defined(WITH_UINPUT) compiled_with_uinput = true; #endif if (detected_xdg_session == "wayland") { if (compiled_with_uinput) { PRINT_STDOUT() << "Selecting uinput as a default event generator."; qInfo() << "uinput is default for wayland"; temp = "uinput"; } else { qWarning() << "Detected wayland session, but there is no support for uinput detected, defaulting to xtest."; temp = "xtest"; } } if (!compiled_with_uinput && !compiled_with_x11) qWarning() << "Neither uinput nor xtest support is detected."; identifier_obtained = true; return temp; #elif defined(Q_OS_WIN) return "sendinput"; #endif } QStringList EventHandlerFactory::buildEventGeneratorList() { QStringList temp = QStringList(); #ifdef Q_OS_WIN temp.append("sendinput"); #else temp.append("xtest"); temp.append("uinput"); #endif return temp; } QString EventHandlerFactory::handlerDisplayName(QString handler) { QString handlerDispName = QString(); if (handlerDisplayNames.contains(handler)) handlerDispName = handlerDisplayNames.value(handler); return handlerDispName; } AntiMicroX-antimicrox-b300273/src/eventhandlerfactory.h000066400000000000000000000045331471077622000231660ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef EVENTHANDLERFACTORY_H #define EVENTHANDLERFACTORY_H #include #include #ifdef WITH_UINPUT #include "eventhandlers/uinputeventhandler.h" #endif #ifdef WITH_XTEST #include "eventhandlers/xtesteventhandler.h" #endif #ifdef Q_OS_WIN #include "eventhandlers/winsendinputeventhandler.h" #ifdef WITH_VMULTI #include "eventhandlers/winvmultieventhandler.h" #endif #endif #ifdef Q_OS_WIN #define ADD_SENDINPUT 1 #ifdef WITH_VMULTI #define ADD_VMULTI 1 #else #define ADD_VMULTI 0 #endif #define NUM_BACKENDS (ADD_SENDINPUT + ADD_VMULTI) #else #ifdef WITH_XTEST #define ADD_XTEST 1 #else #define ADD_XTEST 0 #endif #ifdef WITH_UINPUT #define ADD_UINPUT 1 #else #define ADD_UINPUT 0 #endif #define NUM_BACKENDS (ADD_XTEST + ADD_UINPUT) #endif #if (NUM_BACKENDS > 1) #define BACKEND_ELSE_IF else if #else #define BACKEND_ELSE_IF if #endif class BaseEventHandler; class EventHandlerFactory : public QObject { Q_OBJECT public: static EventHandlerFactory *getInstance(QString handler = ""); void deleteInstance(); BaseEventHandler *handler(); static QString fallBackIdentifier(); static QStringList buildEventGeneratorList(); static QString handlerDisplayName(QString handler); protected: explicit EventHandlerFactory(QString handler, QObject *parent = nullptr); BaseEventHandler *eventHandler; static EventHandlerFactory *instance; }; #endif // EVENTHANDLERFACTORY_H AntiMicroX-antimicrox-b300273/src/eventhandlers/000077500000000000000000000000001471077622000216035ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/eventhandlers/baseeventhandler.cpp000066400000000000000000000040451471077622000256240ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "baseeventhandler.h" #include "joybuttonslot.h" #include BaseEventHandler::BaseEventHandler(QObject *parent) : QObject(parent) { } BaseEventHandler::~BaseEventHandler() {} QString BaseEventHandler::getErrorString() { return lastErrorString; } /** * @brief Do nothing by default. Allow child classes to specify text to output * to a text stream. */ void BaseEventHandler::printPostMessages() {} /** * @brief Do nothing by default. Useful for child classes to define behavior. * @param Displacement of X coordinate * @param Displacement of Y coordinate * @param Screen number or -1 to use default */ void BaseEventHandler::sendMouseAbsEvent(int xDis, int yDis, int screen) { Q_UNUSED(xDis); Q_UNUSED(yDis); Q_UNUSED(screen); } /** * @brief Do nothing by default. Useful for child classes to define behavior. * @param Displacement of X coordinate * @param Displacement of Y coordinate * @param Bounding box width * @param Bounding box height */ void BaseEventHandler::sendMouseSpringEvent(int xDis, int yDis, int width, int height) { Q_UNUSED(xDis); Q_UNUSED(yDis); Q_UNUSED(width); Q_UNUSED(height); } void BaseEventHandler::sendTextEntryEvent(QString maintext) { Q_UNUSED(maintext); } AntiMicroX-antimicrox-b300273/src/eventhandlers/baseeventhandler.h000066400000000000000000000040311471077622000252640ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BASEEVENTHANDLER_H #define BASEEVENTHANDLER_H #include class JoyButtonSlot; /** * @brief Base class for input event handlers * * It manages mouse movements and keyboard strokes * */ class BaseEventHandler : public QObject { Q_OBJECT public: explicit BaseEventHandler(QObject *parent = nullptr); virtual ~BaseEventHandler(); virtual bool init() = 0; virtual bool cleanup() = 0; virtual void sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) = 0; virtual void sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) = 0; /** * @brief Move cursor to selected relative location (deltax delaty) */ virtual void sendMouseEvent(int xDis, int yDis) = 0; /** * @brief Move cursor to selected absolute location (x, y) on selected display */ virtual void sendMouseAbsEvent(int xDis, int yDis, int screen); virtual void sendMouseSpringEvent(int xDis, int yDis, int width, int height); virtual void sendTextEntryEvent(QString maintext); virtual QString getName() = 0; virtual QString getIdentifier() = 0; virtual void printPostMessages(); QString getErrorString(); protected: QString lastErrorString; }; #endif // BASEEVENTHANDLER_H AntiMicroX-antimicrox-b300273/src/eventhandlers/uinputeventhandler.cpp000066400000000000000000000422271471077622000262420ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include static const QString mouseDeviceName = PadderCommon::mouseDeviceName; static const QString keyboardDeviceName = PadderCommon::keyboardDeviceName; static const QString springMouseDeviceName = PadderCommon::springMouseDeviceName; #ifdef WITH_X11 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) #include #endif #include #endif #include "uinputeventhandler.h" UInputEventHandler::UInputEventHandler(QObject *parent) : BaseEventHandler(parent) #if defined(Q_OS_UNIX) , is_problem_with_opening_uinput_present(false) #endif { keyboardFileHandler = 0; mouseFileHandler = 0; springMouseFileHandler = 0; } UInputEventHandler::~UInputEventHandler() { cleanupUinputEvHand(); } /** * @brief Initialize keyboard and mouse virtual devices. Each device will * use its own file handle with various codes set to distinquish the two * devices. * @return */ bool UInputEventHandler::init() { bool result = true; // Open file handle for keyboard emulation. initDevice(keyboardFileHandler, "keyboardFileHandler", result); // two separate statements for "result" are needed anyway because of possible changing its // statement in "initDevice" method if (result) { // Open mouse file handle to use for relative mouse emulation. initDevice(mouseFileHandler, "mouseFileHandler", result); } if (result) { // Open mouse file handle to use for absolute mouse emulation. initDevice(springMouseFileHandler, "springMouseFileHandler", result); } #ifdef WITH_X11 if (result) { #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) if (QApplication::platformName() == QStringLiteral("xcb")) { #endif // Some time needs to elapse after device creation before changing // pointer settings. Otherwise, settings will not take effect. QTimer::singleShot(2000, this, SLOT(x11ResetMouseAccelerationChange())); #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) } #endif } #endif return result; } void UInputEventHandler::initDevice(int &device, QString name, bool &result) { device = openUInputHandle(); if (device > 0) { if (name == "springMouseFileHandler") { QString detected_xdg_session = qgetenv("XDG_SESSION_TYPE"); if (detected_xdg_session == "x11") qWarning() << "uinput event handle may not work properly with absolute mouse events (like spring mouse) for X11"; // https://stackoverflow.com/questions/5190921/simulating-absolute-mouse-movements-in-linux-using-uinput setSpringMouseEvents(device); createUInputSpringMouseDevice(device); } else if (name == "mouseFileHandler") { setRelMouseEvents(device); createUInputMouseDevice(device); } else if (name == "keyboardFileHandler") { setKeyboardEvents(device); populateKeyCodes(device); createUInputKeyboardDevice(device); } } else { result = false; } } #ifdef WITH_X11 void UInputEventHandler::x11ResetMouseAccelerationChange() { if (X11Extras::getInstance()) { X11Extras::getInstance()->x11ResetMouseAccelerationChange(); } } #endif bool UInputEventHandler::cleanup() { return cleanupUinputEvHand(); } bool UInputEventHandler::cleanupUinputEvHand() { if (keyboardFileHandler > 0) { closeUInputDevice(keyboardFileHandler); keyboardFileHandler = 0; } if (mouseFileHandler > 0) { closeUInputDevice(mouseFileHandler); mouseFileHandler = 0; } if (springMouseFileHandler > 0) { closeUInputDevice(springMouseFileHandler); springMouseFileHandler = 0; } return true; } void UInputEventHandler::sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) { JoyButtonSlot::JoySlotInputAction device = slot->getSlotMode(); int code = slot->getSlotCode(); if (device == JoyButtonSlot::JoyKeyboard) { write_uinput_event(keyboardFileHandler, EV_KEY, code, pressed ? 1 : 0); } } void UInputEventHandler::sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) { JoyButtonSlot::JoySlotInputAction device = slot->getSlotMode(); int code = slot->getSlotCode(); if (device == JoyButtonSlot::JoyMouseButton) { if (code <= 3) { unsigned int tempcode; switch (code) { case 3: { tempcode = BTN_RIGHT; break; } case 2: { tempcode = BTN_MIDDLE; break; } case 1: default: { tempcode = BTN_LEFT; } } write_uinput_event(mouseFileHandler, EV_KEY, tempcode, pressed ? 1 : 0); } else if (code == 4) { if (pressed) { write_uinput_event(mouseFileHandler, EV_REL, REL_WHEEL, 1); } } else if (code == 5) { if (pressed) { write_uinput_event(mouseFileHandler, EV_REL, REL_WHEEL, -1); } } else if (code == 6) { if (pressed) { write_uinput_event(mouseFileHandler, EV_REL, REL_HWHEEL, -1); } } else if (code == 7) { if (pressed) { write_uinput_event(mouseFileHandler, EV_REL, REL_HWHEEL, 1); } } else if (code == 8) { write_uinput_event(mouseFileHandler, EV_KEY, BTN_SIDE, pressed ? 1 : 0); } else if (code == 9) { write_uinput_event(mouseFileHandler, EV_KEY, BTN_EXTRA, pressed ? 1 : 0); } } } void UInputEventHandler::sendMouseEvent(int xDis, int yDis) { write_uinput_event(mouseFileHandler, EV_REL, REL_X, xDis, false); write_uinput_event(mouseFileHandler, EV_REL, REL_Y, yDis); } void UInputEventHandler::sendMouseAbsEvent(int xDis, int yDis, int screen) { Q_UNUSED(screen); write_uinput_event(springMouseFileHandler, EV_ABS, ABS_X, xDis, false); write_uinput_event(springMouseFileHandler, EV_ABS, ABS_Y, yDis); } void UInputEventHandler::sendMouseSpringEvent(int xDis, int yDis, int width, int height) { if ((width > 0) && (height > 0)) { double midwidth = width / 2.0; double midheight = height / 2.0; int fx = ceil(32767 * ((xDis - midwidth) / midwidth)); int fy = ceil(32767 * ((yDis - midheight) / midheight)); sendMouseAbsEvent(fx, fy, -1); } } int UInputEventHandler::openUInputHandle() { int filehandle = -1; QStringList locations; locations.append("/dev/input/uinput"); locations.append("/dev/uinput"); locations.append("/dev/misc/uinput"); QString possibleLocation; for (auto &&temp : locations) { QFileInfo tempFileInfo(temp); if (tempFileInfo.exists()) { possibleLocation = temp; break; } } if (possibleLocation.isEmpty()) { lastErrorString = tr("Could not find a valid uinput device file.\n" "Please check that you have the uinput module loaded.\n" "lsmod | grep uinput"); } else { QByteArray tempArray = possibleLocation.toUtf8(); filehandle = open(tempArray.constData(), O_WRONLY | O_NONBLOCK); if (filehandle < 0) { lastErrorString = tr("Could not open uinput device file\n" "Please check that you have permission to write to the device"); lastErrorString.append(": ").append(possibleLocation).append('\n'); #if defined(Q_OS_UNIX) is_problem_with_opening_uinput_present = true; #endif } else { uinputDeviceLocation = possibleLocation; } } return filehandle; } void UInputEventHandler::setKeyboardEvents(int filehandle) { ioctl(filehandle, UI_SET_EVBIT, EV_KEY); ioctl(filehandle, UI_SET_EVBIT, EV_SYN); } void UInputEventHandler::setRelMouseEvents(int filehandle) { ioctl(filehandle, UI_SET_EVBIT, EV_KEY); ioctl(filehandle, UI_SET_EVBIT, EV_SYN); ioctl(filehandle, UI_SET_EVBIT, EV_REL); ioctl(filehandle, UI_SET_RELBIT, REL_X); ioctl(filehandle, UI_SET_RELBIT, REL_Y); ioctl(filehandle, UI_SET_RELBIT, REL_WHEEL); ioctl(filehandle, UI_SET_RELBIT, REL_HWHEEL); ioctl(filehandle, UI_SET_KEYBIT, BTN_LEFT); ioctl(filehandle, UI_SET_KEYBIT, BTN_RIGHT); ioctl(filehandle, UI_SET_KEYBIT, BTN_MIDDLE); ioctl(filehandle, UI_SET_KEYBIT, BTN_SIDE); ioctl(filehandle, UI_SET_KEYBIT, BTN_EXTRA); } void UInputEventHandler::setSpringMouseEvents(int filehandle) { ioctl(filehandle, UI_SET_EVBIT, EV_KEY); ioctl(filehandle, UI_SET_EVBIT, EV_SYN); ioctl(filehandle, UI_SET_KEYBIT, BTN_LEFT); ioctl(filehandle, UI_SET_KEYBIT, BTN_RIGHT); ioctl(filehandle, UI_SET_KEYBIT, BTN_MIDDLE); ioctl(filehandle, UI_SET_KEYBIT, BTN_SIDE); ioctl(filehandle, UI_SET_KEYBIT, BTN_EXTRA); ioctl(filehandle, UI_SET_EVBIT, EV_ABS); ioctl(filehandle, UI_SET_ABSBIT, ABS_X); ioctl(filehandle, UI_SET_ABSBIT, ABS_Y); ioctl(filehandle, UI_SET_KEYBIT, BTN_TOUCH); } void UInputEventHandler::populateKeyCodes(int filehandle) { for (unsigned int i = KEY_ESC; i <= KEY_MICMUTE; i++) { ioctl(filehandle, UI_SET_KEYBIT, i); } } void UInputEventHandler::createUInputKeyboardDevice(int filehandle) { struct uinput_user_dev uidev; memset(&uidev, 0, sizeof(uidev)); QByteArray temp = keyboardDeviceName.toUtf8(); strncpy(uidev.name, temp.constData(), UINPUT_MAX_NAME_SIZE); uidev.id.bustype = BUS_USB; uidev.id.vendor = 0x0; uidev.id.product = 0x0; uidev.id.version = 1; write(filehandle, &uidev, sizeof(uidev)); ioctl(filehandle, UI_DEV_CREATE); } void UInputEventHandler::createUInputMouseDevice(int filehandle) { struct uinput_user_dev uidev; memset(&uidev, 0, sizeof(uidev)); QByteArray temp = mouseDeviceName.toUtf8(); strncpy(uidev.name, temp.constData(), UINPUT_MAX_NAME_SIZE); uidev.id.bustype = BUS_USB; uidev.id.vendor = 0x0; uidev.id.product = 0x0; uidev.id.version = 1; write(filehandle, &uidev, sizeof(uidev)); ioctl(filehandle, UI_DEV_CREATE); } void UInputEventHandler::createUInputSpringMouseDevice(int filehandle) { struct uinput_user_dev uidev; memset(&uidev, 0, sizeof(uidev)); QByteArray temp = springMouseDeviceName.toUtf8(); strncpy(uidev.name, temp.constData(), UINPUT_MAX_NAME_SIZE); uidev.id.bustype = BUS_USB; uidev.id.vendor = 0x0; uidev.id.product = 0x0; uidev.id.version = 1; uidev.absmin[ABS_X] = -32767; uidev.absmax[ABS_X] = 32767; uidev.absflat[ABS_X] = 0; uidev.absmin[ABS_Y] = -32767; uidev.absmax[ABS_Y] = 32767; uidev.absflat[ABS_Y] = 0; write(filehandle, &uidev, sizeof(uidev)); ioctl(filehandle, UI_DEV_CREATE); } void UInputEventHandler::closeUInputDevice(int filehandle) { ioctl(filehandle, UI_DEV_DESTROY); close(filehandle); } void UInputEventHandler::write_uinput_event(int filehandle, int type, int code, int value, bool syn) { struct input_event ev; struct input_event ev2; memset(&ev, 0, sizeof(struct input_event)); gettimeofday(&ev.time, nullptr); ev.type = type; ev.code = code; ev.value = value; write(filehandle, &ev, sizeof(struct input_event)); if (syn) { memset(&ev2, 0, sizeof(struct input_event)); gettimeofday(&ev2.time, nullptr); ev2.type = EV_SYN; ev2.code = SYN_REPORT; ev2.value = 0; write(filehandle, &ev2, sizeof(struct input_event)); } } QString UInputEventHandler::getName() { return QString("uinput"); } QString UInputEventHandler::getIdentifier() { return getName(); } /** * @brief Print extra help messages to stdout. */ void UInputEventHandler::printPostMessages() { if (!lastErrorString.isEmpty()) { PRINT_STDERR() << lastErrorString; #if defined(Q_OS_UNIX) if (is_problem_with_opening_uinput_present) { QMessageBox msgBox; msgBox.setTextFormat(Qt::RichText); msgBox.setText( QObject::tr("Unable to open uinput files, this may cause problems with generating events.\nTo check " "possible solutions please visit: ") .append( "AntiMicroX Wiki")); msgBox.setDetailedText(lastErrorString); msgBox.exec(); } #endif } if (!uinputDeviceLocation.isEmpty()) { qInfo() << tr("Using uinput device file %1").arg(uinputDeviceLocation); } } void UInputEventHandler::sendTextEntryEvent(QString maintext) { AntKeyMapper *mapper = AntKeyMapper::getInstance(); if ((mapper != nullptr) && mapper->getKeyMapper()) { QtUInputKeyMapper *keymapper = qobject_cast(mapper->getKeyMapper()); #ifdef WITH_X11 QtX11KeyMapper *nativeWinKeyMapper = nullptr; if (mapper->getNativeKeyMapper()) { nativeWinKeyMapper = qobject_cast(mapper->getNativeKeyMapper()); } #endif QList tempList; for (int i = 0; i < maintext.size(); i++) { tempList.clear(); QtUInputKeyMapper::charKeyInformation temp; temp.virtualkey = 0; temp.modifiers = Qt::NoModifier; #ifdef WITH_X11 if (nativeWinKeyMapper != nullptr) { QtX11KeyMapper::charKeyInformation tempX11 = nativeWinKeyMapper->getCharKeyInformation(maintext.at(i)); tempX11.virtualkey = X11Extras::getInstance()->getGroup1KeySym(tempX11.virtualkey); unsigned int tempQtKey = nativeWinKeyMapper->returnQtKey(tempX11.virtualkey); if (tempQtKey > 0) { temp.virtualkey = keymapper->returnVirtualKey(tempQtKey); temp.modifiers = tempX11.modifiers; } else { temp = keymapper->getCharKeyInformation(maintext.at(i)); } } else { #endif temp = keymapper->getCharKeyInformation(maintext.at(i)); #ifdef WITH_X11 } #endif if (temp.virtualkey > KEY_RESERVED) { if (temp.modifiers != Qt::NoModifier) { testAndAppend(temp.modifiers.testFlag(Qt::ShiftModifier), tempList, KEY_LEFTSHIFT); testAndAppend(temp.modifiers.testFlag(Qt::ControlModifier), tempList, KEY_LEFTCTRL); testAndAppend(temp.modifiers.testFlag(Qt::AltModifier), tempList, KEY_LEFTALT); testAndAppend(temp.modifiers.testFlag(Qt::MetaModifier), tempList, KEY_LEFTMETA); } tempList.append(temp.virtualkey); write_uinput_event(keyboardFileHandler, EV_KEY, temp.virtualkey, 1, true); } if (tempList.size() > 0) { for (auto iter = tempList.crbegin(); iter != tempList.crend(); ++iter) { unsigned int currentcode = *iter; bool sync = std::next(iter) == tempList.crend(); write_uinput_event(keyboardFileHandler, EV_KEY, currentcode, 0, sync); } } } } } void UInputEventHandler::testAndAppend(bool tested, QList &tempList, unsigned int key) { if (tested) { tempList.append(key); write_uinput_event(keyboardFileHandler, EV_KEY, key, 1, false); } } int UInputEventHandler::getKeyboardFileHandler() { return keyboardFileHandler; } int UInputEventHandler::getMouseFileHandler() { return mouseFileHandler; } int UInputEventHandler::getSpringMouseFileHandler() { return springMouseFileHandler; } const QString UInputEventHandler::getUinputDeviceLocation() { return uinputDeviceLocation; } AntiMicroX-antimicrox-b300273/src/eventhandlers/uinputeventhandler.h000066400000000000000000000070311471077622000257010ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef UINPUTEVENTHANDLER_H #define UINPUTEVENTHANDLER_H #include "baseeventhandler.h" /** * @brief Input event handler class using uinput files * * Proper udev rule may be needed for usage * General info * https://kernel.org/doc/html/v5.15/input/uinput.html * Event types * https://www.kernel.org/doc/html/v5.15/input/event-codes.html * */ class UInputEventHandler : public BaseEventHandler { Q_OBJECT public: explicit UInputEventHandler(QObject *parent = nullptr); ~UInputEventHandler(); virtual bool init() override; virtual bool cleanup() override; virtual void sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) override; virtual void sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) override; virtual void sendMouseEvent(int xDis, int yDis) override; virtual void sendMouseAbsEvent(int xDis, int yDis, int screen) override; virtual void sendMouseSpringEvent(int xDis, int yDis, int width, int height) override; virtual QString getName() override; virtual QString getIdentifier() override; virtual void printPostMessages() override; virtual void sendTextEntryEvent(QString maintext) override; int getKeyboardFileHandler(); int getMouseFileHandler(); int getSpringMouseFileHandler(); const QString getUinputDeviceLocation(); protected: int openUInputHandle(); void setKeyboardEvents(int filehandle); void setRelMouseEvents(int filehandle); void setSpringMouseEvents(int filehandle); void populateKeyCodes(int filehandle); void createUInputKeyboardDevice(int filehandle); void createUInputMouseDevice(int filehandle); void createUInputSpringMouseDevice(int filehandle); void closeUInputDevice(int filehandle); /** * @brief Write uinput event to selected file uinput file * * @param filehandle - C-style linux file handle obtained by open() * @param type type of event described in input-event-codes.h (for example EV_ABS ) * @param code Additional code like ABS_X for type EV_ABS * @param value * @param syn synchronize after event (emit additional event used for separation of events EV_SYN) */ void write_uinput_event(int filehandle, int type, int code, int value, bool syn = true); private slots: #ifdef WITH_X11 void x11ResetMouseAccelerationChange(); #endif private: int keyboardFileHandler; int mouseFileHandler; int springMouseFileHandler; QString uinputDeviceLocation; #if defined(Q_OS_UNIX) bool is_problem_with_opening_uinput_present; #endif bool cleanupUinputEvHand(); void testAndAppend(bool tested, QList &tempList, unsigned int key); void initDevice(int &device, QString name, bool &result); }; #endif // UINPUTEVENTHANDLER_H AntiMicroX-antimicrox-b300273/src/eventhandlers/winsendinputeventhandler.cpp000066400000000000000000000164701471077622000274460ustar00rootroot00000000000000/* antimicro Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "winsendinputeventhandler.h" #include #include WinSendInputEventHandler::WinSendInputEventHandler(QObject *parent) : BaseEventHandler(parent) { } bool WinSendInputEventHandler::init() { return true; } bool WinSendInputEventHandler::cleanup() { return true; } void WinSendInputEventHandler::sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) { int code = slot->getSlotCode(); INPUT temp[1] = {}; unsigned int scancode = WinExtras::scancodeFromVirtualKey(code, slot->getSlotCodeAlias()); int extended = (scancode & WinExtras::EXTENDED_FLAG) != 0; int tempflags = extended ? KEYEVENTF_EXTENDEDKEY : 0; temp[0].type = INPUT_KEYBOARD; // temp[0].ki.wScan = MapVirtualKey(code, MAPVK_VK_TO_VSC); temp[0].ki.wScan = scancode; temp[0].ki.time = 0; temp[0].ki.dwExtraInfo = 0; temp[0].ki.wVk = code; temp[0].ki.dwFlags = pressed ? tempflags : (tempflags | KEYEVENTF_KEYUP); // 0 for key press SendInput(1, temp, sizeof(INPUT)); } void WinSendInputEventHandler::sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) { int code = slot->getSlotCode(); INPUT temp[1] = {}; temp[0].type = INPUT_MOUSE; if (code == 1) { temp[0].mi.dwFlags = pressed ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP; } else if (code == 2) { temp[0].mi.dwFlags = pressed ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP; } else if (code == 3) { temp[0].mi.dwFlags = pressed ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP; } else if (code == 4) { temp[0].mi.dwFlags = MOUSEEVENTF_WHEEL; temp[0].mi.mouseData = pressed ? WHEEL_DELTA : 0; } else if (code == 5) { temp[0].mi.dwFlags = MOUSEEVENTF_WHEEL; temp[0].mi.mouseData = pressed ? -WHEEL_DELTA : 0; } else if (code == 6) { temp[0].mi.dwFlags = 0x01000; temp[0].mi.mouseData = pressed ? -WHEEL_DELTA : 0; } else if (code == 7) { temp[0].mi.dwFlags = 0x01000; temp[0].mi.mouseData = pressed ? WHEEL_DELTA : 0; } else if (code == 8) { temp[0].mi.dwFlags = pressed ? MOUSEEVENTF_XDOWN : MOUSEEVENTF_XUP; temp[0].mi.mouseData = XBUTTON1; } else if (code == 9) { temp[0].mi.dwFlags = pressed ? MOUSEEVENTF_XDOWN : MOUSEEVENTF_XUP; temp[0].mi.mouseData = XBUTTON2; } SendInput(1, temp, sizeof(INPUT)); } void WinSendInputEventHandler::sendMouseEvent(int xDis, int yDis) { INPUT temp[1] = {}; temp[0].type = INPUT_MOUSE; temp[0].mi.mouseData = 0; temp[0].mi.dwFlags = MOUSEEVENTF_MOVE; temp[0].mi.dx = xDis; temp[0].mi.dy = yDis; SendInput(1, temp, sizeof(INPUT)); } QString WinSendInputEventHandler::getName() { return QString("SendInput"); } QString WinSendInputEventHandler::getIdentifier() { return QString("sendinput"); } void WinSendInputEventHandler::sendMouseSpringEvent(int xDis, int yDis, int width, int height) { if (width > 0 && height > 0) { INPUT temp[1] = {}; temp[0].type = INPUT_MOUSE; temp[0].mi.mouseData = 0; temp[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; int fx = ceil(xDis * (65535.0 / static_cast(width))); int fy = ceil(yDis * (65535.0 / static_cast(height))); temp[0].mi.dx = fx; temp[0].mi.dy = fy; SendInput(1, temp, sizeof(INPUT)); } } void WinSendInputEventHandler::sendTextEntryEvent(QString maintext) { AntKeyMapper *mapper = AntKeyMapper::getInstance(); if (mapper && mapper->getKeyMapper()) { QtWinKeyMapper *keymapper = static_cast(mapper->getKeyMapper()); for (int i = 0; i < maintext.size(); i++) { QtWinKeyMapper::charKeyInformation temp = keymapper->getCharKeyInformation(maintext.at(i)); QList tempList; if (temp.modifiers != Qt::NoModifier) { if (temp.modifiers.testFlag(Qt::ShiftModifier)) { tempList.append(VK_LSHIFT); } if (temp.modifiers.testFlag(Qt::ControlModifier)) { tempList.append(VK_LCONTROL); } if (temp.modifiers.testFlag(Qt::AltModifier)) { tempList.append(VK_LMENU); } if (temp.modifiers.testFlag(Qt::MetaModifier)) { tempList.append(VK_LWIN); } } tempList.append(temp.virtualkey); int inputCount = tempList.size(); if (inputCount > 0) { QVarLengthArray tempBuffer(inputCount); unsigned int j = 0; for (auto iter = tempList.cbegin(); iter != tempList.cend(); ++iter, ++j) { unsigned int tempcode = *iter; unsigned int scancode = WinExtras::scancodeFromVirtualKey(tempcode); int extended = (scancode & WinExtras::EXTENDED_FLAG) != 0; int tempflags = extended ? KEYEVENTF_EXTENDEDKEY : 0; tempBuffer[j].type = INPUT_KEYBOARD; tempBuffer[j].ki.wScan = scancode; tempBuffer[j].ki.time = 0; tempBuffer[j].ki.dwExtraInfo = 0; tempBuffer[j].ki.wVk = tempcode; tempBuffer[j].ki.dwFlags = tempflags; } SendInput(j, tempBuffer.data(), sizeof(INPUT)); j = 0; memset(tempBuffer.data(), 0, sizeof(INPUT) * inputCount); // INPUT tempBuffer2[tempList.size()] = {0}; for (auto iter = tempList.crbegin(); iter != tempList.crend(); ++iter, ++j) { unsigned int tempcode = *iter; unsigned int scancode = WinExtras::scancodeFromVirtualKey(tempcode); int extended = (scancode & WinExtras::EXTENDED_FLAG) != 0; int tempflags = extended ? KEYEVENTF_EXTENDEDKEY : 0; tempBuffer[j].type = INPUT_KEYBOARD; tempBuffer[j].ki.wScan = scancode; tempBuffer[j].ki.time = 0; tempBuffer[j].ki.dwExtraInfo = 0; tempBuffer[j].ki.wVk = tempcode; tempBuffer[j].ki.dwFlags = tempflags | KEYEVENTF_KEYUP; } SendInput(j, tempBuffer.data(), sizeof(INPUT)); } } } } AntiMicroX-antimicrox-b300273/src/eventhandlers/winsendinputeventhandler.h000066400000000000000000000033321471077622000271040ustar00rootroot00000000000000/* antimicro Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef WINSENDINPUTEVENTHANDLER_H #define WINSENDINPUTEVENTHANDLER_H #include #include "baseeventhandler.h" #include /** * @brief Input event handler class for Windows * * It utilizes SendInput functions * */ class WinSendInputEventHandler : public BaseEventHandler { Q_OBJECT public: explicit WinSendInputEventHandler(QObject *parent = 0); virtual bool init() override; virtual bool cleanup() override; virtual void sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) override; virtual void sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) override; virtual void sendMouseEvent(int xDis, int yDis) override; virtual void sendMouseSpringEvent(int xDis, int yDis, int width, int height) override; virtual void sendTextEntryEvent(QString maintext) override; virtual QString getName() override; virtual QString getIdentifier() override; signals: public slots: }; #endif // WINSENDINPUTEVENTHANDLER_H AntiMicroX-antimicrox-b300273/src/eventhandlers/winvmultieventhandler.cpp000066400000000000000000000235511471077622000267530ustar00rootroot00000000000000/* antimicro Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ //#include #include #include #include #include "winvmultieventhandler.h" #include WinVMultiEventHandler::WinVMultiEventHandler(QObject *parent) : BaseEventHandler(parent) , sendInputHandler(this) { vmulti = 0; mouseButtons = 0; shiftKeys = 0; multiKeys = 0; extraKeys = 0; keyboardKeys.resize(6); keyboardKeys.fill(0); nativeKeyMapper = 0; } WinVMultiEventHandler::~WinVMultiEventHandler() { cleanup(); } bool WinVMultiEventHandler::init() { bool result = true; vmulti = vmulti_alloc(); if (vmulti == NULL) { result = false; } if (vmulti && !vmulti_connect(vmulti)) { vmulti_free(vmulti); vmulti = 0; result = false; } if (vmulti) { nativeKeyMapper = 0; if (AntKeyMapper::getInstance("vmulti")->hasNativeKeyMapper()) { nativeKeyMapper = AntKeyMapper::getInstance("vmulti")->getNativeKeyMapper(); } } return result; } bool WinVMultiEventHandler::cleanup() { bool result = true; if (vmulti) { vmulti_disconnect(vmulti); vmulti_free(vmulti); vmulti = 0; } nativeKeyMapper = 0; return result; } void WinVMultiEventHandler::sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) { int code = slot->getSlotCode(); BYTE pendingShift = 0x0; BYTE pendingMultimedia = 0x0; BYTE pendingExtra = 0x0; BYTE pendingKey = 0x0; JoyButtonSlot tempSendInputSlot(slot); bool useSendInput = false; bool exists = keyboardKeys.contains(code); if (code <= 0x65) { pendingKey = code; } else if (code >= 0xE0 && code <= 0xE7) { // pendingShift = 1 << (code - 0xE0); if (nativeKeyMapper) { unsigned int nativeKey = nativeKeyMapper->returnVirtualKey(slot->getSlotCodeAlias()); if (nativeKey > 0) { tempSendInputSlot.setSlotCode(nativeKey); useSendInput = true; } } } else if (code > QtVMultiKeyMapper::consumerUsagePagePrefix) { if (nativeKeyMapper) { unsigned int nativeKey = nativeKeyMapper->returnVirtualKey(slot->getSlotCodeAlias()); if (nativeKey > 0) { tempSendInputSlot.setSlotCode(nativeKey); useSendInput = true; } } /*if (code == 0xB5 | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingMultimedia = 1 << 0; // (Scan Next Track) } else if (code == 0xB6 | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingMultimedia = 1 << 1; // (Scan Previous Track) } else if (code == 0xB1 | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingMultimedia = 1 << 3; // (Play / Pause) } else if (code == 0x189 | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingMultimedia = 1 << 6; // (WWW Home) } else if (code == 0x194 | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingExtra = 1 << 0; // (My Computer) } else if (code == 0x192 | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingExtra = 1 << 1; // (Calculator) } else if (code == 0x22a | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingExtra = 1 << 2; // (WWW fav) } else if (code == 0x221 | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingExtra = 1 << 3; // (WWW search) } else if (code == 0xB7 | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingExtra = 1 << 3; // (WWW stop) } else if (code == 0x224 | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingExtra = 1 << 4; // (WWW back) } else if (code == 0x87 | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingExtra = 1 << 5; // (Media Select) } else if (code == 0x18a | QtVMultiKeyMapper::consumerUsagePagePrefix) { pendingExtra = 1 << 6; // (Mail) } */ } else if (code > 0x65) { if (nativeKeyMapper) { unsigned int nativeKey = nativeKeyMapper->returnVirtualKey(slot->getSlotCodeAlias()); if (nativeKey > 0) { tempSendInputSlot.setSlotCode(nativeKey); // sendInputHandler.sendKeyboardEvent(tempslot, pressed); useSendInput = true; } } /*if (code == 0x78) { pendingMultimedia = 1 << 2; // (Stop) } else if (code == 0x7F) { pendingMultimedia = 1 << 4; // (Mute) } else if (code == 0x81) { pendingMultimedia = 1 << 5; // (Volume Down) } else if (code == 0x80) { pendingMultimedia = 1 << 6; // (Volume Up) } */ } if (!useSendInput) { if (pressed) { shiftKeys = shiftKeys | pendingShift; multiKeys = multiKeys | pendingMultimedia; extraKeys = extraKeys | pendingExtra; if (!exists) { // Check for an empty key value int index = keyboardKeys.indexOf(0); if (index != -1) { keyboardKeys.replace(index, pendingKey); } } } else { shiftKeys = shiftKeys ^ pendingShift; multiKeys = multiKeys ^ pendingMultimedia; extraKeys = extraKeys ^ pendingExtra; if (exists) { int index = keyboardKeys.indexOf(pendingKey); if (index != -1) { keyboardKeys.replace(index, 0); } } } BYTE *keykeyArray = keyboardKeys.data(); /*QStringList trying; for (int i=0; i < 6; i++) { BYTE current = keykeyArray[i]; trying.append(QString("0x%1").arg(QString::number(current, 16))); } */ // qDebug() << "CURRENT: " << trying.join(","); // qDebug() << keykeyArray; if (pendingKey > 0x0) { vmulti_update_keyboard(vmulti, shiftKeys, keykeyArray); } if (pendingMultimedia > 0 || pendingExtra > 0) { // vmulti_update_keyboard_enhanced(vmulti, multiKeys, extraKeys); } } else { sendInputHandler.sendKeyboardEvent(&tempSendInputSlot, pressed); useSendInput = false; } } void WinVMultiEventHandler::sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) { BYTE pendingButton = 0; BYTE pendingWheel = 0; BYTE pendingHWheel = 0; bool useSendInput = false; int code = slot->getSlotCode(); if (code == 1) { pendingButton = 0x01; } else if (code == 2) { pendingButton = 0x04; } else if (code == 3) { pendingButton = 0x02; } else if (code == 4) { pendingWheel = pressed ? 1 : 0; } else if (code == 5) { pendingWheel = pressed ? -1 : 0; } else if (code >= 6 && code <= 9) { useSendInput = true; } /* else if (code == 6) { pendingHWheel = pressed ? -1 : 0; } else if (code == 7) { pendingHWheel = pressed ? 1 : 0; } else if (code == 8) { pendingButton = 0x08; } else if (code == 9) { pendingButton = 0x10; } */ if (!useSendInput) { if (pressed) { mouseButtons = mouseButtons | pendingButton; vmulti_update_relative_mouse(vmulti, mouseButtons, 0, 0, pendingWheel); //, pendingHWheel); } else { mouseButtons = mouseButtons ^ pendingButton; vmulti_update_relative_mouse(vmulti, mouseButtons, 0, 0, pendingWheel); //, pendingHWheel); } } else { sendInputHandler.sendMouseButtonEvent(slot, pressed); } } void WinVMultiEventHandler::sendMouseEvent(int xDis, int yDis) { vmulti_update_relative_mouse(vmulti, mouseButtons, xDis, yDis, 0); //, 0); } void WinVMultiEventHandler::sendMouseSpringEvent(unsigned int xDis, unsigned int yDis, unsigned int width, unsigned int height) { if (width > 0 && height > 0) { int fx = ceil(xDis * (32767.0 / static_cast(width))); int fy = ceil(yDis * (32767.0 / static_cast(height))); sendMouseAbsEvent(fx, fy, -1); } } void WinVMultiEventHandler::sendMouseAbsEvent(int xDis, int yDis, int screen) { Q_UNUSED(screen); vmulti_update_mouse(vmulti, mouseButtons, xDis, yDis, 0); //, 0); } /* * TODO: Implement text event using information from QtWinKeyMapper. */ void WinVMultiEventHandler::sendTextEntryEvent(QString maintext) { sendInputHandler.sendTextEntryEvent(maintext); } QString WinVMultiEventHandler::getName() { return QString("Vmulti"); } QString WinVMultiEventHandler::getIdentifier() { return QString("vmulti"); } AntiMicroX-antimicrox-b300273/src/eventhandlers/winvmultieventhandler.h000066400000000000000000000041111471077622000264070ustar00rootroot00000000000000/* antimicro Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef WINVMULTIEVENTHANDLER_H #define WINVMULTIEVENTHANDLER_H #include #include #include "baseeventhandler.h" #include #include #include "winsendinputeventhandler.h" #include class WinVMultiEventHandler : public BaseEventHandler { Q_OBJECT public: explicit WinVMultiEventHandler(QObject *parent = 0); ~WinVMultiEventHandler(); virtual bool init(); virtual bool cleanup(); virtual void sendKeyboardEvent(JoyButtonSlot *slot, bool pressed); virtual void sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed); virtual void sendMouseEvent(int xDis, int yDis); virtual void sendMouseAbsEvent(int xDis, int yDis, int screen); virtual void sendMouseSpringEvent(unsigned int xDis, unsigned int yDis, unsigned int width, unsigned int height); // TODO: Implement text event using information from QtWinKeyMapper. virtual void sendTextEntryEvent(QString maintext); virtual QString getName(); virtual QString getIdentifier(); protected: pvmulti_client vmulti; BYTE mouseButtons; BYTE shiftKeys; BYTE multiKeys; BYTE extraKeys; QVector keyboardKeys; WinSendInputEventHandler sendInputHandler; QtKeyMapperBase *nativeKeyMapper; signals: public slots: }; #endif // WINVMULTIEVENTHANDLER_H AntiMicroX-antimicrox-b300273/src/eventhandlers/xtesteventhandler.cpp000066400000000000000000000134401471077622000260600ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "xtesteventhandler.h" #include "antkeymapper.h" #include "globalvariables.h" #include "joybuttonslot.h" #include #include #include #include "x11extras.h" XTestEventHandler::XTestEventHandler(QObject *parent) : BaseEventHandler(parent) { } XTestEventHandler::~XTestEventHandler() {} bool XTestEventHandler::init() { X11Extras *instance = X11Extras::getInstance(); if (instance != nullptr) { instance->x11ResetMouseAccelerationChange(GlobalVariables::X11Extras::xtestMouseDeviceName); } return true; } bool XTestEventHandler::cleanup() { return true; } void XTestEventHandler::sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) { Display *display = X11Extras::getInstance()->display(); JoyButtonSlot::JoySlotInputAction device = slot->getSlotMode(); int code = slot->getSlotCode(); if (device == JoyButtonSlot::JoyKeyboard) { int tempcode = XKeysymToKeycode(display, static_cast(code)); if (tempcode > 0) { XTestFakeKeyEvent(display, tempcode, pressed, 0); XFlush(display); } } } void XTestEventHandler::sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) { Display *display = X11Extras::getInstance()->display(); JoyButtonSlot::JoySlotInputAction device = slot->getSlotMode(); int code = slot->getSlotCode(); if (device == JoyButtonSlot::JoyMouseButton) { XTestFakeButtonEvent(display, code, pressed, 0); XFlush(display); } } void XTestEventHandler::sendMouseEvent(int xDis, int yDis) { Display *display = X11Extras::getInstance()->display(); XTestFakeRelativeMotionEvent(display, xDis, yDis, 0); XFlush(display); } void XTestEventHandler::sendMouseAbsEvent(int xDis, int yDis, int screen) { Display *display = X11Extras::getInstance()->display(); XTestFakeMotionEvent(display, screen, xDis, yDis, 0); XFlush(display); } QString XTestEventHandler::getName() { return QString("XTest"); } QString XTestEventHandler::getIdentifier() { return QString("xtest"); } void XTestEventHandler::sendTextEntryEvent(QString maintext) { AntKeyMapper *mapper = AntKeyMapper::getInstance(); if ((mapper != nullptr) && mapper->getKeyMapper()) { Display *display = X11Extras::getInstance()->display(); QtX11KeyMapper *keymapper = qobject_cast(mapper->getKeyMapper()); for (int i = 0; i < maintext.size(); i++) { QtX11KeyMapper::charKeyInformation temp = keymapper->getCharKeyInformation(maintext.at(i)); int tempcode = XKeysymToKeycode(display, static_cast(temp.virtualkey)); if (tempcode > 0) { QList tempList; if ((temp.modifiers != Qt::NoModifier) && temp.modifiers.testFlag(Qt::ShiftModifier)) { int shiftcode = XKeysymToKeycode(display, XK_Shift_L); int modifiercode = shiftcode; XTestFakeKeyEvent(display, modifiercode, 1, 0); tempList.append(modifiercode); } if ((temp.modifiers != Qt::NoModifier) && temp.modifiers.testFlag(Qt::ControlModifier)) { int controlcode = XKeysymToKeycode(display, XK_Control_L); int modifiercode = controlcode; XTestFakeKeyEvent(display, modifiercode, 1, 0); tempList.append(modifiercode); } if ((temp.modifiers != Qt::NoModifier) && temp.modifiers.testFlag(Qt::AltModifier)) { int altcode = XKeysymToKeycode(display, XK_Alt_L); int modifiercode = altcode; XTestFakeKeyEvent(display, modifiercode, 1, 0); tempList.append(modifiercode); } if ((temp.modifiers != Qt::NoModifier) && temp.modifiers.testFlag(Qt::MetaModifier)) { int metacode = XKeysymToKeycode(display, XK_Meta_L); int modifiercode = metacode; XTestFakeKeyEvent(display, modifiercode, 1, 0); tempList.append(modifiercode); } XTestFakeKeyEvent(display, tempcode, 1, 0); tempList.append(tempcode); XFlush(display); if (tempList.size() > 0) { for (auto iter = tempList.crbegin(); iter != tempList.crend(); ++iter) { int currentcode = *iter; XTestFakeKeyEvent(display, currentcode, 0, 0); } XFlush(display); } } } } } void XTestEventHandler::sendMouseSpringEvent(int xDis, int yDis, int width, int height) { Q_UNUSED(xDis); Q_UNUSED(yDis); Q_UNUSED(width); Q_UNUSED(height); } void XTestEventHandler::printPostMessages() {} AntiMicroX-antimicrox-b300273/src/eventhandlers/xtesteventhandler.h000066400000000000000000000032571471077622000255320ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef XTESTEVENTHANDLER_H #define XTESTEVENTHANDLER_H #include "baseeventhandler.h" class JoyButtonSlot; class XTestEventHandler : public BaseEventHandler { Q_OBJECT public: explicit XTestEventHandler(QObject *parent = nullptr); virtual ~XTestEventHandler(); bool init() override; bool cleanup() override; void sendKeyboardEvent(JoyButtonSlot *slot, bool pressed) override; void sendMouseButtonEvent(JoyButtonSlot *slot, bool pressed) override; void sendMouseEvent(int xDis, int yDis) override; void sendMouseAbsEvent(int xDis, int yDis, int screen) override; void sendMouseSpringEvent(int xDis, int yDis, int width, int height) override; void sendTextEntryEvent(QString maintext) override; QString getName() override; QString getIdentifier() override; void printPostMessages() override; }; #endif // XTESTEVENTHANDLER_H AntiMicroX-antimicrox-b300273/src/fakeclasses/000077500000000000000000000000001471077622000212255ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/fakeclasses/xbox360wireless.cpp000066400000000000000000000057051471077622000247270ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define MAKE_CONTROLLER_ID(nVID, nPID) (unsigned int)(nVID << 16 | nPID) #include "xbox360wireless.h" //#include "SDL-mirror/src/joystick/SDL_sysjoystick.h" Xbox360Wireless::Xbox360Wireless() { SDL_Joystick Xbox360; Xbox360.instance_id = 0; Xbox360.name = name(); Xbox360.player_index = 0; Xbox360.guid = joyGUID(); Xbox360.naxes = 6; Xbox360.nhats = 0; Xbox360.nbuttons = 15; // Xbox360.nballs = 0; if (Xbox360.naxes > 0) { Xbox360.axes = (SDL_JoystickAxisInfo *)SDL_calloc(Xbox360.naxes, sizeof(SDL_JoystickAxisInfo)); } if (Xbox360.nhats > 0) { Xbox360.hats = (Uint8 *)SDL_calloc(Xbox360.nhats, sizeof(Uint8)); } // if (Xbox360.nballs > 0) { // Xbox360.balls = (struct balldelta *) SDL_calloc(Xbox360.balls, sizeof(*Xbox360.balls)); // } if (Xbox360.nbuttons > 0) { Xbox360.buttons = (Uint8 *)SDL_calloc(Xbox360.nbuttons, sizeof(Uint8)); } Xbox360.attached = SDL_TRUE; Xbox360.is_game_controller = SDL_TRUE; Xbox360.epowerlevel = SDL_JOYSTICK_POWER_MEDIUM; Xbox360.ref_count = 1; Xbox360.next = NULL; // _SDL_JoystickDriver - it's faked class so there is no need to use detection from system level result = &Xbox360; } Xbox360Wireless::~Xbox360Wireless() { SDL_free(result->name); /* Free the data associated with this joystick */ SDL_free(result->axes); SDL_free(result->hats); SDL_free(result->balls); SDL_free(result->buttons); SDL_free(result); } char *Xbox360Wireless::GUID() { return "030000005e040000e002000000000000"; } char *Xbox360Wireless::name() { return "Xbox Wireless Controller"; } unsigned int Xbox360Wireless::deviceId() { return MAKE_CONTROLLER_ID(0x045e, 0x0291); } int Xbox360Wireless::controllerType() { return 31; // k_eControllerType_XBox360Controller } SDL_JoystickType Xbox360Wireless::joystickType() { return SDL_JoystickType::SDL_JOYSTICK_TYPE_GAMECONTROLLER; } SDL_JoystickGUID Xbox360Wireless::joyGUID() { return SDL_JoystickGetGUIDFromString(GUID()); } SDL_Joystick *Xbox360Wireless::getResult() { return result; } AntiMicroX-antimicrox-b300273/src/fakeclasses/xbox360wireless.h000066400000000000000000000061031471077622000243650ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef XBOX360WIRELESS_H #define XBOX360WIRELESS_H #include typedef struct _SDL_JoystickAxisInfo { Sint16 initial_value; /* Initial axis state */ Sint16 value; /* Current axis state */ Sint16 zero; /* Zero point on the axis (-32768 for triggers) */ SDL_bool has_initial_value; /* Whether we've seen a value on the axis yet */ SDL_bool sent_initial_value; /* Whether we've sent the initial axis value */ } SDL_JoystickAxisInfo; struct _SDL_Joystick { SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */ char *name; /* Joystick name - system dependent */ int player_index; /* Joystick player index, or -1 if unavailable */ SDL_JoystickGUID guid; /* Joystick guid */ int naxes; /* Number of axis controls on the joystick */ SDL_JoystickAxisInfo *axes; int nhats; /* Number of hats on the joystick */ Uint8 *hats; /* Current hat states */ int nballs; /* Number of trackballs on the joystick */ struct balldelta { int dx; int dy; } * balls; /* Current ball motion deltas */ int nbuttons; /* Number of buttons on the joystick */ Uint8 *buttons; /* Current button states */ SDL_bool attached; SDL_bool is_game_controller; SDL_bool delayed_guide_button; /* SDL_TRUE if this device has the guide button event delayed */ SDL_bool force_recentering; /* SDL_TRUE if this device needs to have its state reset to 0 */ SDL_JoystickPowerLevel epowerlevel; /* power level of this joystick, SDL_JOYSTICK_POWER_UNKNOWN if not supported */ struct _SDL_JoystickDriver *driver; struct joystick_hwdata *hwdata; /* Driver dependent information */ int ref_count; /* Reference count for multiple opens */ struct _SDL_Joystick *next; /* pointer to next joystick we have allocated */ }; class Xbox360Wireless { public: Xbox360Wireless(); ~Xbox360Wireless(); char *GUID(); char *name(); unsigned int deviceId(); int controllerType(); SDL_JoystickType joystickType(); SDL_JoystickGUID joyGUID(); SDL_Joystick *getResult(); private: SDL_Joystick *result; }; #endif AntiMicroX-antimicrox-b300273/src/gamecontroller/000077500000000000000000000000001471077622000217565ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/gamecontroller/gamecontroller.cpp000066400000000000000000000261301471077622000255010ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "gamecontroller.h" #include "antimicrosettings.h" #include "common.h" #include "gamecontrollerdpad.h" #include "gamecontrollerset.h" #include "globalvariables.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joycontrolstick.h" //#include "logger.h" #include #include #include #include #include GameController::GameController(SDL_GameController *controller, int deviceIndex, AntiMicroSettings *settings, int counterUniques, QObject *parent) : InputDevice(SDL_GameControllerGetJoystick(controller), deviceIndex, settings, parent) { this->controller = controller; this->counterUniques = counterUniques; SDL_Joystick *joyhandle = SDL_GameControllerGetJoystick(controller); joystickID = SDL_JoystickInstanceID(joyhandle); #if SDL_VERSION_ATLEAST(2, 0, 16) m_controller_type = SDL_GameControllerGetType(controller); #else m_controller_type = SDL_CONTROLLER_TYPE_UNKNOWN; #endif enableSensors(); for (int i = 0; i < GlobalVariables::InputDevice::NUMBER_JOYSETS; i++) { GameControllerSet *controllerset = new GameControllerSet(this, i, this); getJoystick_sets().insert(i, controllerset); enableSetConnections(controllerset); } INFO() << "Created new GameController:\n" << getDescription(); } QString GameController::getName() { return QString(tr("Game Controller")).append(" ").append(QString::number(getRealJoyNumber())); } QString GameController::getSDLName() { QString temp = QString(); if (controller != nullptr) { temp = SDL_GameControllerName(controller); } return temp; } QString GameController::getXmlName() const { return GlobalVariables::GameController::xmlName; } QString GameController::getGUIDString() const { return getRawGUIDString(); } QString GameController::getVendorString() const { return getRawVendorString(); } QString GameController::getProductIDString() const { return getRawProductIDString(); } QString GameController::getSerialString() const { QString temp = QString(); #if SDL_VERSION_ATLEAST(2, 0, 14) if (controller != nullptr) { const char *serial = SDL_GameControllerGetSerial(controller); temp = QString(serial).remove(QRegularExpression("[^A-Za-z0-9]")); } #endif return temp; } QString GameController::getUniqueIDString() const { return getRawUniqueIDString(); } QString GameController::getProductVersion() const { return getRawProductVersion(); } QString GameController::getRawGUIDString() const { QString temp = QString(); if (controller != nullptr) { SDL_Joystick *joyhandle = SDL_GameControllerGetJoystick(controller); if (joyhandle != nullptr) { SDL_JoystickGUID tempGUID = SDL_JoystickGetGUID(joyhandle); char guidString[65] = {'0'}; SDL_JoystickGetGUIDString(tempGUID, guidString, sizeof(guidString)); temp = QString(guidString); } } return temp; } QString GameController::getRawVendorString() const { QString temp = QString(); if (controller != nullptr) { Uint16 tempVendor = SDL_GameControllerGetVendor(controller); char buffer[50]; sprintf(buffer, "%u", tempVendor); temp = QString(buffer); } return temp; } QString GameController::getRawProductIDString() const { QString temp = QString(); if (controller != nullptr) { Uint16 tempProduct = SDL_GameControllerGetProduct(controller) + counterUniques; char buffer[50]; sprintf(buffer, "%u", tempProduct); temp = QString(buffer); } return temp; } QString GameController::getRawProductVersion() const { QString temp = QString(); if (controller != nullptr) { Uint16 tempProductVersion = SDL_GameControllerGetProductVersion(controller); char buffer[50]; sprintf(buffer, "%u", tempProductVersion); temp = QString(buffer); } return temp; } QString GameController::getRawUniqueIDString() const { return (getRawGUIDString() + getRawVendorString() + getRawProductIDString() + getSerialString()); } void GameController::closeSDLDevice() { if ((controller != nullptr) && SDL_GameControllerGetAttached(controller)) { SDL_GameControllerClose(controller); controller = nullptr; } } int GameController::getNumberRawButtons() { return SDL_CONTROLLER_BUTTON_MAX; } int GameController::getNumberRawAxes() { qDebug() << "Controller has " << SDL_CONTROLLER_AXIS_MAX << " raw axes"; return SDL_CONTROLLER_AXIS_MAX; } /** * @brief Queries the data rate of the given sensor from SDL. * @returns Data rate in events per second or zero if data rate is unavailable. */ double GameController::getRawSensorRate(JoySensorType type) { double rate = 0; #if SDL_VERSION_ATLEAST(2, 0, 16) if (type == ACCELEROMETER) rate = SDL_GameControllerGetSensorDataRate(controller, SDL_SENSOR_ACCEL); else if (type == GYROSCOPE) rate = SDL_GameControllerGetSensorDataRate(controller, SDL_SENSOR_GYRO); #endif if (qFuzzyIsNull(rate)) WARN() << "Sensor rate is zero. Some calculations may be inaccurate!"; return rate; } /** * @brief Queries if the hardware has the given sensor type. * @returns True if the sensor is present, false otherwise. */ bool GameController::hasRawSensor(JoySensorType type) { #if SDL_VERSION_ATLEAST(2, 0, 14) if (type == ACCELEROMETER) return SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL); else if (type == GYROSCOPE) return SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO); #endif return false; } int GameController::getNumberRawHats() { return 0; } void GameController::setCounterUniques(int counter) { counterUniques = counter; } QString GameController::getBindStringForAxis(int index, bool) { QString temp = QString(); SDL_GameControllerButtonBind bind = SDL_GameControllerGetBindForAxis(controller, static_cast(index)); if (bind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON) { temp.append(QString("Button %1").arg(bind.value.button)); } else if (bind.bindType == SDL_CONTROLLER_BINDTYPE_AXIS) { temp.append(QString("Axis %1").arg(bind.value.axis + 1)); } return temp; } QString GameController::getBindStringForButton(int index, bool trueIndex) { QString temp = QString(); SDL_GameControllerButtonBind bind = SDL_GameControllerGetBindForButton(controller, static_cast(index)); int offset = trueIndex ? 0 : 1; int bindInt = static_cast(bind.bindType); switch (bindInt) { case SDL_CONTROLLER_BINDTYPE_BUTTON: temp.append(QString("Button %1").arg(bind.value.button + offset)); break; case SDL_CONTROLLER_BINDTYPE_AXIS: temp.append(QString("Axis %1").arg(bind.value.axis + offset)); break; case SDL_CONTROLLER_BINDTYPE_HAT: temp.append(QString("Hat %1.%2").arg(bind.value.hat.hat + offset).arg(bind.value.hat.hat_mask)); break; } return temp; } SDL_GameControllerButtonBind GameController::getBindForAxis(int index) { return SDL_GameControllerGetBindForAxis(controller, static_cast(index)); } SDL_GameControllerButtonBind GameController::getBindForButton(int index) { return SDL_GameControllerGetBindForButton(controller, static_cast(index)); } void GameController::buttonClickEvent(int) {} void GameController::buttonReleaseEvent(int) {} void GameController::enableSensors() { #if SDL_VERSION_ATLEAST(2, 0, 14) if (SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO)) { SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); } if (SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL)) { SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE); } #endif } void GameController::axisActivatedEvent(int, int, int) {} SDL_JoystickID GameController::getSDLJoystickID() { return joystickID; } /** * @brief Check if device is using the SDL Game Controller API * @return Status showing if device is using the Game Controller API */ bool GameController::isGameController() { return true; } /** * @brief Check if GUID passed matches the expected GUID for a device. * Needed for xinput GUID abstraction. * @param GUID string * @return if GUID is considered a match. */ // bool GameController::isRelevantGUID(QString tempGUID) //{ // return InputDevice::isRelevantGUID(tempGUID); //} bool GameController::isRelevantUniqueID(QString tempUniqueID) { return InputDevice::isRelevantUniqueID(tempUniqueID); } void GameController::rawButtonEvent(int index, bool pressed) { bool knownbutton = getRawbuttons().contains(index); if (!knownbutton && pressed) { rawbuttons.insert(index, pressed); emit rawButtonClick(index); } else if (knownbutton && !pressed) { rawbuttons.remove(index); emit rawButtonRelease(index); } } void GameController::rawAxisEvent(int index, int value) { bool knownaxis = getAxisvalues().contains(index); if (!knownaxis && (fabs(value) > rawAxisDeadZone)) { axisvalues.insert(index, value); emit rawAxisActivated(index, value); } else if (knownaxis && (fabs(value) < rawAxisDeadZone)) { axisvalues.remove(index); emit rawAxisReleased(index, value); } emit rawAxisMoved(index, value); } void GameController::rawDPadEvent(int index, int value) { bool knowndpad = getDpadvalues().contains(index); if (!knowndpad && (value != 0)) { dpadvalues.insert(index, value); emit rawDPadButtonClick(index, value); } else if (knowndpad && (value == 0)) { dpadvalues.remove(index); emit rawDPadButtonRelease(index, value); } } QHash const &GameController::getRawbuttons() { return rawbuttons; } QHash const &GameController::getAxisvalues() { return axisvalues; } QHash const &GameController::getDpadvalues() { return dpadvalues; } SDL_GameController *GameController::getController() const { return controller; } /** * @brief Returns the current controller model. */ SDL_GameControllerType GameController::getControllerType() const { return m_controller_type; } AntiMicroX-antimicrox-b300273/src/gamecontroller/gamecontroller.h000066400000000000000000000110221471077622000251400ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GAMECONTROLLER_H #define GAMECONTROLLER_H #include #include class QXmlStreamReader; class QXmlStreamWriter; class AntiMicroSettings; /** * @brief Represents a typical gamepad (like PS4 or Xbox gamepad) * * @details It represents typical gamepads with two analog sticks, one dpad, two shoulder buttons on each side (one of them possibly a trigger axis and not just a button), 4 buttons on the right and some buttons in the middle of the pad. SDL2 maps the axis and buttons of devices it knows (and XInput Devices on Windows) to standardized button/axis names based on xbox360/xinput controllers. It often uses SDL bindings to figure out how gamepad should look like. Every device in this category releases events SDL_CONTROLLER... (like SDL_CONTROLLERBUTTONUP) Each SDL Gamecontroller device can also be used as a bit more general-purposed Joystick device. * * @see https://wiki.libsdl.org/CategoryGameController * @see https://wiki.libsdl.org/SDL_IsGameController */ class GameController : public InputDevice { Q_OBJECT public: explicit GameController(SDL_GameController *controller, int deviceIndex, AntiMicroSettings *settings, int counterUniques, QObject *parent); virtual QString getName() override; virtual QString getSDLName() override; virtual QString getXmlName() const override; // GUID available on SDL 2. virtual QString getGUIDString() const override; virtual QString getVendorString() const override; virtual QString getProductIDString() const override; virtual QString getSerialString() const override; virtual QString getUniqueIDString() const override; virtual QString getRawGUIDString() const override; virtual QString getProductVersion() const override; virtual QString getRawUniqueIDString() const override; virtual QString getRawVendorString() const override; virtual QString getRawProductIDString() const override; virtual QString getRawProductVersion() const override; virtual bool isGameController() override; virtual void closeSDLDevice() override; virtual SDL_JoystickID getSDLJoystickID() override; virtual int getNumberRawButtons() override; virtual int getNumberRawAxes() override; virtual int getNumberRawHats() override; virtual double getRawSensorRate(JoySensorType type) override; virtual bool hasRawSensor(JoySensorType type) override; void setCounterUniques(int counter) override; QString getBindStringForAxis(int index, bool trueIndex = true); QString getBindStringForButton(int index, bool trueIndex = true); SDL_GameControllerButtonBind getBindForAxis(int index); SDL_GameControllerButtonBind getBindForButton(int index); // bool isRelevantGUID(QString tempGUID); bool isRelevantUniqueID(QString tempUniqueID); void rawButtonEvent(int index, bool pressed); void rawAxisEvent(int index, int value); void rawDPadEvent(int index, int value); QHash const &getRawbuttons(); QHash const &getAxisvalues(); QHash const &getDpadvalues(); SDL_GameController *getController() const; virtual SDL_GameControllerType getControllerType() const override; protected slots: virtual void axisActivatedEvent(int setindex, int axisindex, int value) override; virtual void buttonClickEvent(int buttonindex) override; virtual void buttonReleaseEvent(int buttonindex) override; private: QHash rawbuttons; QHash axisvalues; QHash dpadvalues; int counterUniques; SDL_JoystickID joystickID; SDL_GameController *controller; SDL_GameControllerType m_controller_type; void enableSensors(); }; #endif // GAMECONTROLLER_H AntiMicroX-antimicrox-b300273/src/gamecontroller/gamecontrollerdpad.cpp000066400000000000000000000041111471077622000263250ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "gamecontrollerdpad.h" #include "globalvariables.h" #include "joybuttontypes/joybutton.h" #include "setjoystick.h" #include "xml/joydpadxml.h" #include GameControllerDPad::GameControllerDPad(JoyButton *upButton, JoyButton *downButton, JoyButton *leftButton, JoyButton *rightButton, int index, int originset, SetJoystick *parentSet, QObject *parent) : VDPad(upButton, downButton, leftButton, rightButton, index, originset, parentSet, parent) { } QString GameControllerDPad::getName(bool forceFullFormat, bool displayName) { QString label = QString(); if (!getDpadName().isEmpty() && displayName) { if (forceFullFormat) { label.append(tr("DPad")).append(" "); } label.append(getDpadName()); } else if (!getDefaultDpadName().isEmpty()) { if (forceFullFormat) { label.append(tr("DPad")).append(" "); } label.append(getDefaultDpadName()); } else { label.append(tr("DPad")).append(" "); label.append(QString::number(getRealJoyNumber())); } return label; } QString GameControllerDPad::getXmlName() { return GlobalVariables::GameControllerDPad::xmlName; } AntiMicroX-antimicrox-b300273/src/gamecontroller/gamecontrollerdpad.h000066400000000000000000000027211471077622000257770ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GAMECONTROLLERDPAD_H #define GAMECONTROLLERDPAD_H #include "vdpad.h" class QXmlStreamReader; class JoyButton; class SetJoystick; class DPad; // holds information about gamecontroller dpad class GameControllerDPad : public VDPad { Q_OBJECT public: explicit GameControllerDPad(JoyButton *upButton, JoyButton *downButton, JoyButton *leftButton, JoyButton *rightButton, int index, int originset, SetJoystick *parentSet, QObject *parent = nullptr); virtual QString getName(bool forceFullFormat, bool displayName); virtual QString getXmlName(); // GameControllerDPadXml class }; #endif // GAMECONTROLLERDPAD_H AntiMicroX-antimicrox-b300273/src/gamecontroller/gamecontrollerset.cpp000066400000000000000000000223661471077622000262240ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska . */ #include "gamecontrollerset.h" #include "gamecontroller.h" #include "gamecontrollerdpad.h" #include "gamecontrollertrigger.h" #include "haptictriggerps5.h" #include "inputdevice.h" #include "joycontrolstick.h" #include "joysensor.h" #include "xml/joyaxisxml.h" #include "xml/joybuttonxml.h" #include "xml/joydpadxml.h" #include #include GameControllerSet::GameControllerSet(InputDevice *device, int index, QObject *parent) : SetJoystick(device, index, false, parent) { resetSticks(); applyHapticTrigger(); } void GameControllerSet::reset() { resetSticks(); } /** * @brief Applies haptic feedback to the triggers of the controller. * * This fetches the current haptic feedback effects from all triggers of the * controller, builds a low level message and sends the message to the controller. */ void GameControllerSet::applyHapticTrigger() { GameController *controller = qobject_cast(getInputDevice()); HapticTriggerPs5 *left_effect = getJoyAxis(SDL_CONTROLLER_AXIS_TRIGGERLEFT)->getHapticTrigger(); HapticTriggerPs5 *right_effect = getJoyAxis(SDL_CONTROLLER_AXIS_TRIGGERRIGHT)->getHapticTrigger(); if (left_effect == nullptr || right_effect == nullptr) return; HapticTriggerPs5::send(controller->getController(), *left_effect, *right_effect); } void GameControllerSet::resetSticks() { SetJoystick::reset(); populateSticksDPad(); } void GameControllerSet::populateSticksDPad() { // Left Stick Assignment JoyAxis *axisX = getJoyAxis(SDL_CONTROLLER_AXIS_LEFTX); JoyAxis *axisY = getJoyAxis(SDL_CONTROLLER_AXIS_LEFTY); JoyControlStick *stick1 = new JoyControlStick(axisX, axisY, 0, getIndex(), this); stick1->setDefaultStickName("L Stick"); addControlStick(0, stick1); // Right Stick Assignment axisX = getJoyAxis(SDL_CONTROLLER_AXIS_RIGHTX); axisY = getJoyAxis(SDL_CONTROLLER_AXIS_RIGHTY); JoyControlStick *stick2 = new JoyControlStick(axisX, axisY, 1, getIndex(), this); stick2->setDefaultStickName("R Stick"); addControlStick(1, stick2); // Assign DPad buttons as a virtual DPad. Allows rougelike controls // to be assigned. JoyButton *buttonUp = getJoyButton(SDL_CONTROLLER_BUTTON_DPAD_UP); JoyButton *buttonDown = getJoyButton(SDL_CONTROLLER_BUTTON_DPAD_DOWN); JoyButton *buttonLeft = getJoyButton(SDL_CONTROLLER_BUTTON_DPAD_LEFT); JoyButton *buttonRight = getJoyButton(SDL_CONTROLLER_BUTTON_DPAD_RIGHT); GameControllerDPad *controllerDPad = new GameControllerDPad(buttonUp, buttonDown, buttonLeft, buttonRight, 0, getIndex(), this, this); controllerDPad->setDefaultDPadName("DPad"); addVDPad(0, controllerDPad); // Give default names to buttons getJoyButton(SDL_CONTROLLER_BUTTON_A)->setDefaultButtonName("A"); getJoyButton(SDL_CONTROLLER_BUTTON_B)->setDefaultButtonName("B"); getJoyButton(SDL_CONTROLLER_BUTTON_X)->setDefaultButtonName("X"); getJoyButton(SDL_CONTROLLER_BUTTON_Y)->setDefaultButtonName("Y"); getJoyButton(SDL_CONTROLLER_BUTTON_BACK)->setDefaultButtonName(tr("Back")); getJoyButton(SDL_CONTROLLER_BUTTON_GUIDE)->setDefaultButtonName(tr("Guide")); getJoyButton(SDL_CONTROLLER_BUTTON_START)->setDefaultButtonName(tr("Start")); getJoyButton(SDL_CONTROLLER_BUTTON_LEFTSTICK)->setDefaultButtonName(tr("LS Click")); getJoyButton(SDL_CONTROLLER_BUTTON_RIGHTSTICK)->setDefaultButtonName(tr("RS Click")); getJoyButton(SDL_CONTROLLER_BUTTON_LEFTSHOULDER)->setDefaultButtonName(tr("L Shoulder")); getJoyButton(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)->setDefaultButtonName(tr("R Shoulder")); // Give default names to triggers getJoyAxis(SDL_CONTROLLER_AXIS_TRIGGERLEFT)->setDefaultAxisName(tr("L Trigger")); getJoyAxis(SDL_CONTROLLER_AXIS_TRIGGERRIGHT)->setDefaultAxisName(tr("R Trigger")); } template void readConf(T *x, QXmlStreamReader *xml) { if (x != nullptr) { x->readConfig(xml); } else { xml->skipCurrentElement(); } } void GameControllerSet::readConfig(QXmlStreamReader *xml) { if (xml->isStartElement() && (xml->name().toString() == "set")) { xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && xml->name().toString() != "set")) { if ((xml->name().toString() == "button") && xml->isStartElement()) { getElemFromXml("button", xml); } else if ((xml->name().toString() == "trigger") && xml->isStartElement()) { getElemFromXml("trigger", xml); } else if ((xml->name().toString() == "stick") && xml->isStartElement()) { getElemFromXml("stick", xml); } else if ((xml->name().toString() == "sensor") && xml->isStartElement()) { getElemFromXml("sensor", xml); } else if ((xml->name().toString() == "dpad") && xml->isStartElement()) { getElemFromXml("dpad", xml); } else if ((xml->name().toString() == "name") && xml->isStartElement()) { QString temptext = xml->readElementText(); if (!temptext.isEmpty()) { setName(temptext); } } else { // If none of the above, skip the element xml->skipCurrentElement(); } xml->readNextStartElement(); } } } void GameControllerSet::getElemFromXml(QString elemName, QXmlStreamReader *xml) { int index = xml->attributes().value("index").toString().toInt(); if (elemName == "button") { JoyButton *button = getJoyButton(index - 1); JoyButtonXml *joyButtonXml = new JoyButtonXml(button, this); readConf(joyButtonXml, xml); } else if (elemName == "dpad") { GameControllerDPad *vdpad = qobject_cast(getVDPad(index - 1)); JoyDPadXml *dpadXml = new JoyDPadXml(vdpad); readConf(dpadXml, xml); // if (!dpadXml.isNull()) delete dpadXml; } else if (elemName == "trigger") { GameControllerTrigger *axis = nullptr; JoyAxisXml *triggerAxisXml = nullptr; switch (index - 1) { // for older profiles case 0: axis = qobject_cast(getJoyAxis(SDL_CONTROLLER_AXIS_TRIGGERLEFT)); triggerAxisXml = new JoyAxisXml(axis, this); readConf(triggerAxisXml, xml); break; // for older profiles case 1: axis = qobject_cast(getJoyAxis(SDL_CONTROLLER_AXIS_TRIGGERRIGHT)); triggerAxisXml = new JoyAxisXml(axis, this); readConf(triggerAxisXml, xml); break; case 4: axis = qobject_cast(getJoyAxis(SDL_CONTROLLER_AXIS_TRIGGERLEFT)); triggerAxisXml = new JoyAxisXml(axis, this); readConf(triggerAxisXml, xml); break; case 5: axis = qobject_cast(getJoyAxis(SDL_CONTROLLER_AXIS_TRIGGERRIGHT)); triggerAxisXml = new JoyAxisXml(axis, this); readConf(triggerAxisXml, xml); break; } } else if (elemName == "stick") { if (index > 0) { index -= 1; JoyControlStick *stick = getJoyStick(index); readConf(stick, xml); } else { xml->skipCurrentElement(); } } else if (elemName == "sensor") { int type = xml->attributes().value("type").toString().toInt(); JoySensor *sensor = getSensor(static_cast(type)); readConf(sensor, xml); } } void GameControllerSet::refreshAxes() { deleteAxes(); for (int i = 0; i < getInputDevice()->getNumberRawAxes(); i++) { if ((i == static_cast(SDL_CONTROLLER_AXIS_TRIGGERLEFT)) || (i == static_cast(SDL_CONTROLLER_AXIS_TRIGGERRIGHT))) { GameControllerTrigger *trigger = new GameControllerTrigger(i, getIndex(), this, this); getAxes()->insert(i, trigger); enableAxisConnections(trigger); connect(trigger, &JoyAxis::hapticTriggerChanged, this, &GameControllerSet::applyHapticTrigger); } else { JoyAxis *axis = new JoyAxis(i, getIndex(), this, this); getAxes()->insert(i, axis); enableAxisConnections(axis); } } } AntiMicroX-antimicrox-b300273/src/gamecontroller/gamecontrollerset.h000066400000000000000000000030111471077622000256530ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GAMECONTROLLERSET_H #define GAMECONTROLLERSET_H #include "setjoystick.h" #include class QXmlStreamReader; class InputDevice; /** * @brief A SetJoystick specialized for gamepads */ class GameControllerSet : public SetJoystick { Q_OBJECT public: explicit GameControllerSet(InputDevice *device, int index, QObject *parent = nullptr); virtual void refreshAxes(); virtual void readConfig(QXmlStreamReader *xml); protected: void populateSticksDPad(); public slots: virtual void reset(); void applyHapticTrigger(); private: void getElemFromXml(QString elemName, QXmlStreamReader *xml); void resetSticks(); }; #endif // GAMECONTROLLERSET_H AntiMicroX-antimicrox-b300273/src/gamecontroller/gamecontrollertrigger.cpp000066400000000000000000000142771471077622000270760ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska . */ //#include #include "gamecontrollertrigger.h" #include "gamecontrollertriggerbutton.h" #include "globalvariables.h" #include "haptictriggerps5.h" #include "inputdevice.h" #include "setjoystick.h" #include "xml/joyaxisxml.h" #include #include #include #include const GameControllerTrigger::ThrottleTypes GameControllerTrigger::DEFAULTTHROTTLE = GameControllerTrigger::PositiveHalfThrottle; GameControllerTrigger::GameControllerTrigger(int index, int originset, SetJoystick *parentSet, QObject *parent) : JoyAxis(index, originset, parentSet, parent) , m_haptic_trigger(0) { naxisbutton->deleteLater(); naxisbutton = new GameControllerTriggerButton(this, 0, originset, parentSet, this); paxisbutton->deleteLater(); paxisbutton = new GameControllerTriggerButton(this, 1, originset, parentSet, this); reset(index); #if SDL_VERSION_ATLEAST(2, 0, 16) if (parentSet->getInputDevice()->getControllerType() == SDL_GameControllerType::SDL_CONTROLLER_TYPE_PS5) m_haptic_trigger = new HapticTriggerPs5(this); #endif } void GameControllerTrigger::reset(int index) { reset(); m_index = index; } void GameControllerTrigger::reset() { deadZone = GlobalVariables::GameControllerTrigger::AXISDEADZONE; isActive = false; eventActive = false; maxZoneValue = GlobalVariables::GameControllerTrigger::AXISMAXZONE; throttle = this->DEFAULTTHROTTLE; paxisbutton->reset(); naxisbutton->reset(); activeButton = nullptr; lastKnownThottledValue = 0; lastKnownRawValue = 0; adjustRange(); setCurrentRawValue(currentThrottledDeadValue); currentThrottledValue = calculateThrottledValue(currentRawValue); axisName.clear(); pendingEvent = false; pendingValue = currentRawValue; pendingIgnoreSets = false; } QString GameControllerTrigger::getXmlName() { return GlobalVariables::GameControllerTrigger::xmlName; } QString GameControllerTrigger::getPartialName(bool forceFullFormat, bool displayNames) { QString label = QString(); if (!axisName.isEmpty() && displayNames) { label.append(axisName); if (forceFullFormat) { label.append(" ").append(tr("Trigger")); } } else if (!defaultAxisName.isEmpty()) { label.append(defaultAxisName); if (forceFullFormat) { label.append(" ").append(tr("Trigger")); } } else { label.append(tr("Trigger")).append(" "); label.append(QString::number(getRealJoyIndex() - SDL_CONTROLLER_AXIS_TRIGGERLEFT)); } return label; } void GameControllerTrigger::correctJoystickThrottle() { if (this->throttle != static_cast(PositiveHalfThrottle)) { this->setThrottle(static_cast(PositiveHalfThrottle)); setCurrentRawValue(currentThrottledDeadValue); currentThrottledValue = calculateThrottledValue(currentRawValue); } } int GameControllerTrigger::getDefaultDeadZone() { return GlobalVariables::GameControllerTrigger::AXISDEADZONE; } int GameControllerTrigger::getDefaultMaxZone() { return GlobalVariables::GameControllerTrigger::AXISMAXZONE; } JoyAxis::ThrottleTypes GameControllerTrigger::getDefaultThrottle() { return static_cast(this->DEFAULTTHROTTLE); } /** * @brief Checks if the trigger supports haptic feedback. * @returns True if the trigger supports haptic feedback, false otherwise. */ bool GameControllerTrigger::hasHapticTrigger() const { return m_haptic_trigger != 0; } /** * @brief Recalculates haptic trigger effect positions, e.g. after dead zone change, * and returns the current HapticTriggerPs5 object. * @returns Pointer to HapticTriggerPs5 object of this trigger. */ HapticTriggerPs5 *GameControllerTrigger::getHapticTrigger() const { if (m_haptic_trigger == nullptr) return nullptr; int start, end; switch (m_haptic_trigger->get_mode()) { case HAPTIC_TRIGGER_NONE: m_haptic_trigger->set_effect(0, 0, 0); break; case HAPTIC_TRIGGER_CLICK: end = std::max(160, 200 * deadZone / GlobalVariables::JoyAxis::AXISMAX + 60); start = end - 97; m_haptic_trigger->set_effect(GlobalVariables::HapticTriggerPs5::CLICKSTRENGTH, start, end); break; case HAPTIC_TRIGGER_RIGID: m_haptic_trigger->set_effect(GlobalVariables::HapticTriggerPs5::RIGIDSTRENGTH, 0, GlobalVariables::HapticTriggerPs5::RANGE); break; case HAPTIC_TRIGGER_RIGID_GRADIENT: m_haptic_trigger->set_effect(GlobalVariables::HapticTriggerPs5::RIGIDGRADIENTSTRENGTH, 0, GlobalVariables::HapticTriggerPs5::RANGE); break; case HAPTIC_TRIGGER_VIBRATION: start = 200 * deadZone / GlobalVariables::JoyAxis::AXISMAX; m_haptic_trigger->set_effect(GlobalVariables::HapticTriggerPs5::VIBRATIONSTRENGTH, start, GlobalVariables::HapticTriggerPs5::RANGE, GlobalVariables::HapticTriggerPs5::FREQUENCY); break; } return m_haptic_trigger; } /** * @brief Changes the haptic feedback effect mode. * @param[in] mode New haptic feedback effect mode. */ void GameControllerTrigger::setHapticTriggerMode(HapticTriggerModePs5 mode) { if (m_haptic_trigger == 0) return; if (m_haptic_trigger->set_effect_mode(mode)) emit hapticTriggerChanged(); } AntiMicroX-antimicrox-b300273/src/gamecontroller/gamecontrollertrigger.h000066400000000000000000000035561471077622000265410ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GAMECONTROLLERTRIGGER_H #define GAMECONTROLLERTRIGGER_H #include "joyaxis.h" class HapticTriggerPs5; class QXmlStreamReader; class QXmlStreamWriter; class SetJoystick; class GameControllerTrigger : public JoyAxis { Q_OBJECT public: explicit GameControllerTrigger(int index, int originset, SetJoystick *parentSet, QObject *parent = nullptr); virtual QString getXmlName(); // GameControllerTriggerXml class virtual QString getPartialName(bool forceFullFormat, bool displayNames); virtual int getDefaultDeadZone(); virtual int getDefaultMaxZone(); virtual ThrottleTypes getDefaultThrottle(); static const ThrottleTypes DEFAULTTHROTTLE; virtual bool hasHapticTrigger() const override; virtual HapticTriggerPs5 *getHapticTrigger() const override; virtual void setHapticTriggerMode(HapticTriggerModePs5 mode) override; public slots: virtual void reset(); virtual void reset(int index); protected: void correctJoystickThrottle(); HapticTriggerPs5 *m_haptic_trigger; }; #endif // GAMECONTROLLERTRIGGER_H AntiMicroX-antimicrox-b300273/src/gamecontroller/gamecontrollertriggerbutton.cpp000066400000000000000000000026141471077622000303220ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska . */ #include "gamecontrollertriggerbutton.h" #include "globalvariables.h" #include "inputdevice.h" #include "joyaxis.h" #include "setjoystick.h" #include "xml/joybuttonxml.h" #include #include GameControllerTriggerButton::GameControllerTriggerButton(JoyAxis *axis, int index, int originset, SetJoystick *parentSet, QObject *parent) : JoyAxisButton(axis, index, originset, parentSet, parent) { } QString GameControllerTriggerButton::getXmlName() { return GlobalVariables::GameControllerTriggerButton::xmlName; } AntiMicroX-antimicrox-b300273/src/gamecontroller/gamecontrollertriggerbutton.h000066400000000000000000000024431471077622000277670ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GAMECONTROLLERBUTTON_H #define GAMECONTROLLERBUTTON_H #include "joybuttontypes/joyaxisbutton.h" class QXmlStreamReader; class SetJoystick; class JoyAxis; class GameControllerTriggerButton : public JoyAxisButton { Q_OBJECT public: explicit GameControllerTriggerButton(JoyAxis *axis, int index, int originset, SetJoystick *parentSet, QObject *parent = nullptr); virtual QString getXmlName(); }; #endif // GAMECONTROLLERBUTTON_H AntiMicroX-antimicrox-b300273/src/gamecontrollerexample.cpp000066400000000000000000000102221471077622000240330ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska . */ #include "gamecontrollerexample.h" #include #include #include #include #include struct ButtonImagePlacement { int x; int y; GameControllerExample::ButtonType buttontype; }; static ButtonImagePlacement buttonLocations[] = { {225, 98, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_A {252, 77, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_B {200, 77, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_X {227, 59, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_Y {102, 77, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_BACK {169, 77, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_START {137, 77, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_GUIDE {45, 23, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_LEFTSHOULDER {232, 21, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_RIGHTSHOULDER {44, 90, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_LEFTSTICK {179, 135, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_RIGHTSTICK {44, 90, GameControllerExample::AxisX}, // SDL_CONTROLLER_AXIS_LEFTX {44, 90, GameControllerExample::AxisY}, // SDL_CONTROLLER_AXIS_LEFTY {179, 135, GameControllerExample::AxisX}, // SDL_CONTROLLER_AXIS_RIGHTX {179, 135, GameControllerExample::AxisY}, // SDL_CONTROLLER_AXIS_RIGHTY {53, 0, GameControllerExample::Button}, // SDL_CONTROLLER_AXIS_TRIGGERLEFT {220, 0, GameControllerExample::Button}, // SDL_CONTROLLER_AXIS_TRIGGERRIGHT {90, 110, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_DPAD_UP {68, 127, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_DPAD_DOWN {90, 146, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_DPAD_LEFT {109, 127, GameControllerExample::Button}, // SDL_CONTROLLER_BUTTON_DPAD_RIGHT }; GameControllerExample::GameControllerExample(QWidget *parent) : QWidget(parent) { controllerimage = QImage(":/images/controllermap.svg"); buttonimage = QImage(":/images/button.png"); axisimage = QImage(":/images/axis.png"); QTransform myTransform; myTransform.rotate(90); rotatedaxisimage = axisimage.transformed(myTransform); currentIndex = 0; connect(this, &GameControllerExample::indexUpdated, this, [=]() { update(); }); } void GameControllerExample::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter paint(this); // 300x186 is hardcoded size of original image paint.drawImage(QRect(0, 0, 300, 186), controllerimage); ButtonImagePlacement current = buttonLocations[currentIndex]; paint.setOpacity(0.85); switch (current.buttontype) { case Button: paint.drawImage(QRect(current.x, current.y, buttonimage.width(), buttonimage.height()), buttonimage); break; case AxisX: paint.drawImage(QRect(current.x, current.y, axisimage.width(), axisimage.height()), axisimage); break; case AxisY: paint.drawImage(QRect(current.x, current.y, rotatedaxisimage.width(), rotatedaxisimage.height()), rotatedaxisimage); break; } paint.setOpacity(1.0); } void GameControllerExample::setActiveButton(int button) { if (button <= MAXBUTTONINDEX) { currentIndex = button; emit indexUpdated(button); } } AntiMicroX-antimicrox-b300273/src/gamecontrollerexample.h000066400000000000000000000031671471077622000235120ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GAMECONTROLLEREXAMPLE_H #define GAMECONTROLLEREXAMPLE_H #include #include class QPaintEvent; /** * @brief Widget representing image of reference Xbox controller * * It can also mark selected buttons * */ class GameControllerExample : public QWidget { Q_OBJECT public: explicit GameControllerExample(QWidget *parent = nullptr); enum ButtonType { Button, AxisX, AxisY, }; static const int MAXBUTTONINDEX = 20; protected: virtual void paintEvent(QPaintEvent *event); signals: void indexUpdated(int index); public slots: void setActiveButton(int button); private: QImage controllerimage; QImage buttonimage; QImage axisimage; QImage rotatedaxisimage; int currentIndex; }; #endif // GAMECONTROLLEREXAMPLE_H AntiMicroX-antimicrox-b300273/src/globalvariables.cpp000066400000000000000000000232411471077622000226000ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "globalvariables.h" #include "common.h" #include // ---- JOYBUTTON --- // const QString GlobalVariables::JoyButton::xmlName = "button"; // Set default values for many properties. const int GlobalVariables::JoyButton::ENABLEDTURBODEFAULT = 100; const double GlobalVariables::JoyButton::DEFAULTMOUSESPEEDMOD = 1.0; double GlobalVariables::JoyButton::mouseSpeedModifier = GlobalVariables::JoyButton::DEFAULTMOUSESPEEDMOD; const int GlobalVariables::JoyButton::DEFAULTKEYREPEATDELAY = 600; // 600 ms const int GlobalVariables::JoyButton::DEFAULTKEYREPEATRATE = 40; // 40 ms. 25 times per second const bool GlobalVariables::JoyButton::DEFAULTTOGGLE = false; const int GlobalVariables::JoyButton::DEFAULTTURBOINTERVAL = 0; const bool GlobalVariables::JoyButton::DEFAULTUSETURBO = false; const int GlobalVariables::JoyButton::DEFAULTMOUSESPEEDX = 50; const int GlobalVariables::JoyButton::DEFAULTMOUSESPEEDY = 50; const int GlobalVariables::JoyButton::MAXMOUSESPEED = 300; const int GlobalVariables::JoyButton::DEFAULTSETSELECTION = -1; const int GlobalVariables::JoyButton::DEFAULTSPRINGWIDTH = 0; const int GlobalVariables::JoyButton::DEFAULTSPRINGHEIGHT = 0; const double GlobalVariables::JoyButton::DEFAULTSENSITIVITY = 1.0; const int GlobalVariables::JoyButton::DEFAULTWHEELX = 20; const int GlobalVariables::JoyButton::DEFAULTWHEELY = 20; const bool GlobalVariables::JoyButton::DEFAULTCYCLERESETACTIVE = false; const int GlobalVariables::JoyButton::DEFAULTCYCLERESET = 0; const bool GlobalVariables::JoyButton::DEFAULTRELATIVESPRING = false; const double GlobalVariables::JoyButton::DEFAULTEASINGDURATION = 0.5; const double GlobalVariables::JoyButton::MINIMUMEASINGDURATION = 0.2; const double GlobalVariables::JoyButton::MAXIMUMEASINGDURATION = 5.0; const int GlobalVariables::JoyButton::MINCYCLERESETTIME = 10; const int GlobalVariables::JoyButton::MAXCYCLERESETTIME = 60000; const int GlobalVariables::JoyButton::DEFAULTMOUSEHISTORYSIZE = 10; const double GlobalVariables::JoyButton::DEFAULTWEIGHTMODIFIER = 0.2; const int GlobalVariables::JoyButton::MAXIMUMMOUSEHISTORYSIZE = 100; const double GlobalVariables::JoyButton::MAXIMUMWEIGHTMODIFIER = 1.0; const int GlobalVariables::JoyButton::MAXIMUMMOUSEREFRESHRATE = 16; int GlobalVariables::JoyButton::IDLEMOUSEREFRESHRATE = (5 * 20); const int GlobalVariables::JoyButton::DEFAULTIDLEMOUSEREFRESHRATE = 100; const double GlobalVariables::JoyButton::DEFAULTEXTRACCELVALUE = 2.0; const double GlobalVariables::JoyButton::DEFAULTMINACCELTHRESHOLD = 10.0; const double GlobalVariables::JoyButton::DEFAULTMAXACCELTHRESHOLD = 100.0; const double GlobalVariables::JoyButton::DEFAULTSTARTACCELMULTIPLIER = 0.0; const double GlobalVariables::JoyButton::DEFAULTACCELEASINGDURATION = 0.1; const int GlobalVariables::JoyButton::DEFAULTSPRINGRELEASERADIUS = 0; // Keep references to active keys and mouse buttons. QHash GlobalVariables::JoyButton::activeKeys; QHash GlobalVariables::JoyButton::activeMouseButtons; // History buffers used for mouse smoothing routine. QList GlobalVariables::JoyButton::mouseHistoryX; QList GlobalVariables::JoyButton::mouseHistoryY; // Carry over remainder of a cursor move for the next mouse event. double GlobalVariables::JoyButton::cursorRemainderX = 0.0; double GlobalVariables::JoyButton::cursorRemainderY = 0.0; double GlobalVariables::JoyButton::weightModifier = 0; // Mouse history buffer size int GlobalVariables::JoyButton::mouseHistorySize = 1; int GlobalVariables::JoyButton::mouseRefreshRate = 5; int GlobalVariables::JoyButton::springModeScreen = -1; int GlobalVariables::JoyButton::gamepadRefreshRate = 10; // ---- ANTIMICROSETTINGS --- // const bool GlobalVariables::AntimicroSettings::defaultDisabledWinEnhanced = false; const bool GlobalVariables::AntimicroSettings::defaultAssociateProfiles = true; const int GlobalVariables::AntimicroSettings::defaultSpringScreen = -1; const int GlobalVariables::AntimicroSettings::defaultSDLGamepadPollRate = 10; // unsigned // ---- INPUTDEVICE ---- // const int GlobalVariables::InputDevice::NUMBER_JOYSETS = 8; const int GlobalVariables::InputDevice::DEFAULTKEYPRESSTIME = 100; const int GlobalVariables::InputDevice::RAISEDDEADZONE = 20000; const int GlobalVariables::InputDevice::DEFAULTKEYREPEATDELAY = 660; // 660 ms const int GlobalVariables::InputDevice::DEFAULTKEYREPEATRATE = 40; // 40 ms. 25 times per second // QRegularExpression GlobalVariables::InputDevice::emptyGUID("^[0]+$"); QRegularExpression GlobalVariables::InputDevice::emptyUniqueID("^[0]+$"); // ---- JOYAXIS ---- // // Set default values for many properties. const int GlobalVariables::JoyAxis::AXISMIN = -32767; const int GlobalVariables::JoyAxis::AXISMAX = 32767; const int GlobalVariables::JoyAxis::AXISDEADZONE = 6000; const int GlobalVariables::JoyAxis::AXISMAXZONE = 32000; // Speed in pixels/second const float GlobalVariables::JoyAxis::JOYSPEED = 20.0; const QString GlobalVariables::JoyAxis::xmlName = "axis"; const int GlobalVariables::HapticTriggerPs5::CLICKSTRENGTH = 256; const int GlobalVariables::HapticTriggerPs5::RIGIDSTRENGTH = 128; const int GlobalVariables::HapticTriggerPs5::RIGIDGRADIENTSTRENGTH = 256; const int GlobalVariables::HapticTriggerPs5::VIBRATIONSTRENGTH = 64; const int GlobalVariables::HapticTriggerPs5::RANGE = 320; const int GlobalVariables::HapticTriggerPs5::FREQUENCY = 32; #ifdef WITH_X11 // ---- X11EXTRAS ---- // const QString GlobalVariables::X11Extras::mouseDeviceName = PadderCommon::mouseDeviceName; const QString GlobalVariables::X11Extras::keyboardDeviceName = PadderCommon::keyboardDeviceName; const QString GlobalVariables::X11Extras::xtestMouseDeviceName = QString("Virtual core XTEST pointer"); QString GlobalVariables::X11Extras::_customDisplayString = QString(""); #endif // ---- GameController ---- // const QString GlobalVariables::GameController::xmlName = "gamecontroller"; // ---- GameControllerDPad ---- // const QString GlobalVariables::GameControllerDPad::xmlName = "dpad"; // ---- GameControllerTrigger ---- // const int GlobalVariables::GameControllerTrigger::AXISDEADZONE = 2000; const int GlobalVariables::GameControllerTrigger::AXISMAXZONE = 32000; const QString GlobalVariables::GameControllerTrigger::xmlName = "trigger"; // ---- GameControllerTriggerButton ---- // const QString GlobalVariables::GameControllerTriggerButton::xmlName = "triggerbutton"; // ---- InputDaemon ---- // const int GlobalVariables::InputDaemon::GAMECONTROLLERTRIGGERRELEASE = 16384; // ---- VDPad ---- // const QString GlobalVariables::VDPad::xmlName = "vdpad"; // ---- SetJoystick ---- // const int GlobalVariables::SetJoystick::MAXNAMELENGTH = 30; const int GlobalVariables::SetJoystick::RAISEDDEADZONE = 20000; // ---- Joystick ---- // const QString GlobalVariables::Joystick::xmlName = "joystick"; // ---- JoyDPad ---- // const QString GlobalVariables::JoyDPad::xmlName = "dpad"; const int GlobalVariables::JoyDPad::DEFAULTDPADDELAY = 0; // ---- JoyControlStick ---- // // Define Pi here. const double GlobalVariables::JoyControlStick::PI = acos(-1.0); // Set default values used for stick properties. const int GlobalVariables::JoyControlStick::DEFAULTDEADZONE = 8000; const int GlobalVariables::JoyControlStick::DEFAULTMAXZONE = GlobalVariables::GameControllerTrigger::AXISMAXZONE; const int GlobalVariables::JoyControlStick::DEFAULTMODIFIERZONE = 8000; const bool GlobalVariables::JoyControlStick::DEFAULTMODIFIERZONEINVERTED = false; const int GlobalVariables::JoyControlStick::DEFAULTDIAGONALRANGE = 45; const double GlobalVariables::JoyControlStick::DEFAULTCIRCLE = 0.0; const int GlobalVariables::JoyControlStick::DEFAULTSTICKDELAY = 0; // ---- JoySensor ---- // const double GlobalVariables::JoySensor::ACCEL_MIN = -90.0; const double GlobalVariables::JoySensor::ACCEL_MAX = 90.0; const double GlobalVariables::JoySensor::GYRO_MIN = -360.0; const double GlobalVariables::JoySensor::GYRO_MAX = 360.0; const double GlobalVariables::JoySensor::DEFAULTDEADZONE = 20; const int GlobalVariables::JoySensor::DEFAULTDIAGONALRANGE = 45; const unsigned int GlobalVariables::JoySensor::DEFAULTSENSORDELAY = 0; // ---- JoyButtonSlot ---- // const int GlobalVariables::JoyButtonSlot::JOYSPEED = 20; const QString GlobalVariables::JoyButtonSlot::xmlName = "slot"; const int GlobalVariables::JoyButtonSlot::MAXTEXTENTRYDISPLAYLENGTH = 40; // ---- AdvanceButtonDialog ---- // const int GlobalVariables::AdvanceButtonDialog::MINIMUMTURBO = 2; // ---- JoyAxisButton ---- // const QString GlobalVariables::JoyAxisButton::xmlName = "axisbutton"; // ---- JoyControlStickButton ---- // const QString GlobalVariables::JoyControlStickButton::xmlName = "stickbutton"; // ---- JoyControlStickModifierButton ---- // const QString GlobalVariables::JoyControlStickModifierButton::xmlName = "stickmodifierbutton"; // ---- JoySensorButton ---- // const QString GlobalVariables::JoySensorButton::xmlName = "sensorbutton"; // ---- JoyDPadButton ---- // const QString GlobalVariables::JoyDPadButton::xmlName = "dpadbutton"; AntiMicroX-antimicrox-b300273/src/globalvariables.h000066400000000000000000000152101471077622000222420ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GLOBALVARIABLES_H #define GLOBALVARIABLES_H #include #include #include namespace GlobalVariables { class JoyButton { public: static const QString xmlName; static int IDLEMOUSEREFRESHRATE; static int mouseHistorySize; // Get active mouse movement refresh rate static int mouseRefreshRate; static int springModeScreen; // gamepad poll rate used by the application in ms static int gamepadRefreshRate; static double cursorRemainderX; static double cursorRemainderY; static double mouseSpeedModifier; // Weight modifier in the range of 0.0 - 1.0 static double weightModifier; static const bool DEFAULTTOGGLE; static const bool DEFAULTUSETURBO; static const bool DEFAULTCYCLERESETACTIVE; static const bool DEFAULTRELATIVESPRING; static const double DEFAULTMOUSESPEEDMOD; static const double DEFAULTSENSITIVITY; static const double DEFAULTEASINGDURATION; static const double MINIMUMEASINGDURATION; static const double MAXIMUMEASINGDURATION; static const double DEFAULTWEIGHTMODIFIER; static const double MAXIMUMWEIGHTMODIFIER; static const double DEFAULTEXTRACCELVALUE; static const double DEFAULTMINACCELTHRESHOLD; static const double DEFAULTMAXACCELTHRESHOLD; static const double DEFAULTSTARTACCELMULTIPLIER; static const double DEFAULTACCELEASINGDURATION; // Define default values for many properties. static const int ENABLEDTURBODEFAULT; static const int DEFAULTKEYREPEATDELAY; // unsigned static const int DEFAULTKEYREPEATRATE; // unsigned static const int DEFAULTTURBOINTERVAL; static const int DEFAULTMOUSESPEEDX; static const int DEFAULTMOUSESPEEDY; static const int MAXMOUSESPEED; static const int DEFAULTSETSELECTION; static const int DEFAULTSPRINGWIDTH; static const int DEFAULTSPRINGHEIGHT; static const int DEFAULTWHEELX; static const int DEFAULTWHEELY; static const int DEFAULTCYCLERESET; static const int DEFAULTMOUSEHISTORYSIZE; static const int MAXIMUMMOUSEHISTORYSIZE; static const int MAXIMUMMOUSEREFRESHRATE; static const int DEFAULTIDLEMOUSEREFRESHRATE; static const int MINCYCLERESETTIME; static const int MAXCYCLERESETTIME; static const int DEFAULTSPRINGRELEASERADIUS; static QHash activeKeys; static QHash activeMouseButtons; static QList mouseHistoryX; static QList mouseHistoryY; }; class AntimicroSettings { public: static const bool defaultDisabledWinEnhanced; static const bool defaultAssociateProfiles; static const int defaultSpringScreen; static const int defaultSDLGamepadPollRate; }; class InputDevice { public: static const int NUMBER_JOYSETS; static const int DEFAULTKEYPRESSTIME; static const int RAISEDDEADZONE; static const int DEFAULTKEYREPEATDELAY; static const int DEFAULTKEYREPEATRATE; // static QRegularExpression emptyGUID; static QRegularExpression emptyUniqueID; }; class JoyAxis { public: static const int AXISMIN; static const int AXISMAX; static const int AXISDEADZONE; static const int AXISMAXZONE; static const float JOYSPEED; static const QString xmlName; }; class HapticTriggerPs5 { public: static const int CLICKSTRENGTH; static const int RIGIDSTRENGTH; static const int RIGIDGRADIENTSTRENGTH; static const int VIBRATIONSTRENGTH; static const int RANGE; static const int FREQUENCY; }; #ifdef WITH_X11 class X11Extras { public: static const QString mouseDeviceName; static const QString keyboardDeviceName; static const QString xtestMouseDeviceName; static QString _customDisplayString; }; #endif class GameController { public: static const QString xmlName; }; class GameControllerDPad { public: static const QString xmlName; }; class GameControllerTrigger { public: static const int AXISDEADZONE; static const int AXISMAXZONE; static const QString xmlName; }; class GameControllerTriggerButton { public: static const QString xmlName; }; class InputDaemon { public: static const int GAMECONTROLLERTRIGGERRELEASE; }; class VDPad { public: static const QString xmlName; }; class SetJoystick { public: static const int MAXNAMELENGTH; static const int RAISEDDEADZONE; }; class Joystick { public: static const QString xmlName; }; class JoyDPad { public: static const QString xmlName; static const int DEFAULTDPADDELAY; // unsigned }; class JoyControlStick { public: static const double PI; // Define default values for stick properties. static const int DEFAULTDEADZONE; static const int DEFAULTMAXZONE; static const int DEFAULTMODIFIERZONE; static const bool DEFAULTMODIFIERZONEINVERTED; static const int DEFAULTDIAGONALRANGE; static const double DEFAULTCIRCLE; static const int DEFAULTSTICKDELAY; }; class JoySensor { public: static const double ACCEL_MIN; static const double ACCEL_MAX; static const double GYRO_MIN; static const double GYRO_MAX; static const double DEFAULTDEADZONE; static const int DEFAULTDIAGONALRANGE; static const unsigned int DEFAULTSENSORDELAY; }; class JoyButtonSlot { public: static const int JOYSPEED; static const QString xmlName; static const int MAXTEXTENTRYDISPLAYLENGTH; }; class AdvanceButtonDialog { public: static const int MINIMUMTURBO; }; class JoyAxisButton { public: static const QString xmlName; }; class JoyControlStickButton { public: static const QString xmlName; }; class JoyControlStickModifierButton { public: static const QString xmlName; }; class JoySensorButton { public: static const QString xmlName; }; class JoyDPadButton { public: static const QString xmlName; }; } // namespace GlobalVariables #endif // GLOBALVARIABLES_H AntiMicroX-antimicrox-b300273/src/gui/000077500000000000000000000000001471077622000175255ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/gui/aboutdialog.cpp000066400000000000000000000071561471077622000225340ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "aboutdialog.h" #include "ui_aboutdialog.h" #include "common.h" #include "eventhandlerfactory.h" #include #include #include #include #include #include #include #include #include AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent) , ui(new Ui::AboutDialog) { ui->setupUi(this); ui->versionLabel->setText(PadderCommon::programVersion); fillInfoTextBrowser(); } AboutDialog::~AboutDialog() { delete ui; } void AboutDialog::fillInfoTextBrowser() { QStringList finalInfoText = QStringList(); finalInfoText.append(tr("Program Version %1").arg(PadderCommon::programVersion)); #ifdef ANTIMICROX_PKG_VERSION finalInfoText.append(tr("Compiled from packaging: %1").arg(ANTIMICROX_PKG_VERSION)); #else finalInfoText.append(tr("Program Compiled on %1 at %2").arg(__DATE__).arg(__TIME__)); #endif finalInfoText.append(tr("Built Against SDL %1").arg(PadderCommon::sdlVersionCompiled)); finalInfoText.append(tr("Running With SDL %1").arg(PadderCommon::sdlVersionUsed)); finalInfoText.append(tr("Using Qt %1").arg(qVersion())); BaseEventHandler *handler = nullptr; EventHandlerFactory *factory = EventHandlerFactory::getInstance(); if (factory != nullptr) { handler = factory->handler(); } if (handler != nullptr) { finalInfoText.append(tr("Using Event Handler: %1").arg(handler->getName())); } #ifdef Q_OS_LINUX QString detected_xdg_session = qgetenv("XDG_SESSION_TYPE"); finalInfoText.append(QString("Compositor type: %1").arg(detected_xdg_session)); #endif finalInfoText.append(QString("Host OS: %1 Version: %2 Architecture: %3") .arg(QSysInfo::productType(), QSysInfo::productVersion(), QSysInfo::currentCpuArchitecture())); ui->infoTextBrowser->setText(finalInfoText.join("\n")); // Read Changelog text from resource and put text in text box. QResource changelogFile(":/CHANGELOG.md"); QFile temp(changelogFile.absoluteFilePath()); temp.open(QIODevice::Text | QIODevice::ReadOnly); QTextStream changelogStream(&temp); QString changelogText = changelogStream.readAll(); temp.close(); #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) ui->changelogText->setMarkdown(changelogText); ui->changelogText->setTextInteractionFlags(ui->changelogText->textInteractionFlags() | Qt::LinksAccessibleByMouse); #else ui->changelogText->setPlainText(changelogText); #endif } void AboutDialog::changeEvent(QEvent *event) { if (event->type() == QEvent::LanguageChange) retranslateUi(); QDialog::changeEvent(event); } void AboutDialog::retranslateUi() { ui->retranslateUi(this); ui->versionLabel->setText(PadderCommon::programVersion); } AntiMicroX-antimicrox-b300273/src/gui/aboutdialog.h000066400000000000000000000023451471077622000221740ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ABOUTDIALOG_H #define ABOUTDIALOG_H #include class QEvent; namespace Ui { class AboutDialog; } class AboutDialog : public QDialog { Q_OBJECT public: explicit AboutDialog(QWidget *parent = nullptr); ~AboutDialog(); private: Ui::AboutDialog *ui; protected: void fillInfoTextBrowser(); virtual void changeEvent(QEvent *event); void retranslateUi(); }; #endif // ABOUTDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/aboutdialog.ui000066400000000000000000002122311471077622000223570ustar00rootroot00000000000000 AboutDialog 0 0 640 480 640 480 About 10 6 50 110 0 0 64 64 64 64 :/images/antimicrox.png true false 0 0 14 75 true AntiMicroX Qt::AlignHCenter|Qt::AlignTop 0 -1 0 0 11 Version Qt::AlignCenter 0 false Credits 0 0 IBeamCursor <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Originally developed by Travis Nickles &lt;nickles.travis@gmail.com&gt;. </span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Next maintained by the AntiMicro group at </span><a href="https://github.com/AntiMicro"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/AntiMicro</span></a><span style=" font-family:'Cantarell'; font-size:10pt;">.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Then by juliagoda at </span><a href="https://github.com/juliagoda"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/juliagoda</span></a><span style=" font-family:'Cantarell'; font-size:10pt;">.</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:10pt;">Now maintained at </span><a href="https://github.com/AntiMicroX/antimicrox"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/AntiMicroX/antimicrox</span></a><span style=" font-family:'Cantarell'; font-size:10pt;"> by </span><a href="https://github.com/pktiuk"><span style=" text-decoration: underline; color:#0000ff;">pktiuk</span></a></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Cantarell'; font-size:10pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Contributors:</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">You can see full list of contributors <a href="https://github.com/AntiMicroX/antimicrox/graphs/contributors"><span style=" text-decoration: underline; color:#0000ff;">here</span></a></p></body></html> true Info License 0 0 IBeamCursor <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">GNU GENERAL PUBLIC LICENSE</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Version 3, 29 June 2007</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Preamble</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Developers that use the GNU GPL protect your rights with two steps:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">(1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The precise terms and conditions for copying, distribution and modification follow.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">TERMS AND CONDITIONS</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">0. Definitions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;This License&quot; refers to version 3 of the GNU General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Copyright&quot; also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;The Program&quot; refers to any copyrightable work licensed under this License. Each licensee is addressed as &quot;you&quot;. &quot;Licensees&quot; and &quot;recipients&quot; may be individuals or organizations.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;modify&quot; a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a &quot;modified version&quot; of the earlier work or a work &quot;based on&quot; the earlier work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;covered work&quot; means either the unmodified Program or a work based on the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;propagate&quot; a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To &quot;convey&quot; a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An interactive user interface displays &quot;Appropriate Legal Notices&quot; to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">1. Source Code.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;source code&quot; for a work means the preferred form of the work for making modifications to it. &quot;Object code&quot; means any non-source form of a work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;Standard Interface&quot; means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;System Libraries&quot; of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A &quot;Major Component&quot;, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The &quot;Corresponding Source&quot; for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Corresponding Source for a work in source code form is that same work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">2. Basic Permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">3. Protecting Users' Legal Rights From Anti-Circumvention Law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">4. Conveying Verbatim Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">5. Conveying Modified Source Versions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) The work must carry prominent notices stating that you modified it, and giving a relevant date.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to &quot;keep intact all notices&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an &quot;aggregate&quot; if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">6. Conveying Non-Source Forms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;User Product&quot; is either (1) a &quot;consumer product&quot;, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, &quot;normally used&quot; refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Installation Information&quot; for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">7. Additional Terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">&quot;Additional permissions&quot; are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">d) Limiting the use for publicity purposes of names of licensors or authors of the material; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">All other non-permissive additional terms are considered &quot;further restrictions&quot; within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">8. Termination.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">9. Acceptance Not Required for Having Copies.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">10. Automatic Licensing of Downstream Recipients.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">An &quot;entity transaction&quot; is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">11. Patents.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A &quot;contributor&quot; is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's &quot;contributor version&quot;.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A contributor's &quot;essential patent claims&quot; are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, &quot;control&quot; includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In the following three paragraphs, a &quot;patent license&quot; is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To &quot;grant&quot; such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. &quot;Knowingly relying&quot; means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">A patent license is &quot;discriminatory&quot; if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">12. No Surrender of Others' Freedom.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">13. Use with the GNU Affero General Public License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">14. Revised Versions of this License.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License &quot;or any later version&quot; applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">15. Disclaimer of Warranty.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">16. Limitation of Liability.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">17. Interpretation of Sections 15 and 16.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.</span></p></body></html> false Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse true Changelog true About Development 30 true "pktiuk" (since August 2020) I just want to ensure, that this very useful piece of software will not be abandoned, I decided to continue providing support for this project and make it as widely accessible as possible. "juliagoda" (since March, 2018 until 2020) Wanting only to play my favourite old games that din't support gamepads, I found this project (which map keyboard keys and mouse buttons to connected gamepads on Linux) as most proper and recent. But because of poor choices of such application on the internet and since it didn't compile properly, I decided to rescue the project. However, once I finished my work (enough to enjoy playing games) I thought about sharing this code with others. Of course all information about past programmers will be held. "Ryochan7" (since December 30, 2012 until 2017), I have been working on AntiMicro in my spare time. What originally started as a fork of QJoyPad and a way to learn proper event-driven programming has turned into something much bigger than I originally intended. Although I have spent a lot of time learning new techniques, finding out more about the domain of KB+M emulation, and spending Friday nights bashing my head against my keyboard, it has been a fun and enriching experience overall. The need for this program came from me using similar programs on Windows to play several games that did not provide native controller support. Although some alternatives existed on Linux, there wasn't really anything that I felt was good enough in terms of functionality or in-game controls in order to really enjoy games that I wanted to play with using KB+M emulation. QJoyPad was the main program that I had used in the past although it had aged a lot and it didn't provide some basic functionality that I thought was essential. The project was dead as it had not been updated in several years so I decided to make my own. Since then, I have tried to find out what the other programs do right and then improve upon it. I have also discovered some neat tricks along the way and I have learned more about how native gamepad controls are implemented in some games than I ever really wanted to know. Although there are definitely areas where this program could improve, I find that this program offers the best in-game control experience for playing older, and some newer, games that do not provide native controller support. Development of this program is not as high of a priority for me anymore. This is mainly due to the fact that the Steam Controller works pretty well for the task of playing PC games compared to using an Xbox 360 controller. However, it does look like there is still a reason for this program to exist for a while. --- As of May 24, 2016, this project has moved to https://github.com/AntiMicro/antimicro. Additionally, project management has passed from Travis (Ryochan7) to the AntiMicro organization due to Travis having other interests and priorities. As next, project has been continued since 2018 by juliagoda on antimicroX project. Later project has been once more moved to https://github.com/AntiMicroX/antimicrox and it's its maintenance is continued by organisation AntiMicroX created by pktiuk. Copyright: 2013 - 2022 Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing -1 Qt::Horizontal 40 20 QDialogButtonBox::Close buttonBox accepted() AboutDialog accept() 63 473 319 239 buttonBox rejected() AboutDialog reject() 478 462 319 239 AntiMicroX-antimicrox-b300273/src/gui/addeditautoprofiledialog.cpp000066400000000000000000000430421471077622000252640ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "addeditautoprofiledialog.h" #include "ui_addeditautoprofiledialog.h" #include "antimicrosettings.h" #include "autoprofileinfo.h" #include "common.h" #include "inputdevice.h" #if defined(Q_OS_UNIX) #ifdef WITH_X11 #include "capturedwindowinfodialog.h" #include "unixcapturewindowutility.h" #include "x11extras.h" #endif #elif defined(Q_OS_WIN) #include "capturedwindowinfodialog.h" #include "winappprofiletimerdialog.h" #include "winextras.h" #endif #include #include #include #include #include #include #include AddEditAutoProfileDialog::AddEditAutoProfileDialog(AutoProfileInfo *info, AntiMicroSettings *settings, QList *devices, QList &reservedUniques, bool edit, QWidget *parent) : QDialog(parent) , ui(new Ui::AddEditAutoProfileDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); this->info = info; this->settings = settings; this->editForm = edit; this->devices = devices; this->originalUniqueID = info->getUniqueID(); this->originalExe = info->getExe(); this->originalWindowClass = info->getWindowClass(); this->originalWindowName = info->getWindowName(); if (info->isPartialState()) ui->setPartialCheckBox->setChecked(true); else ui->setPartialCheckBox->setChecked(false); QListIterator iterUniques(reservedUniques); while (iterUniques.hasNext()) { QString uniqueID = iterUniques.next(); if (!getReservedUniques().contains(uniqueID)) this->reservedUniques.append(uniqueID); } ui->devicesComboBox->addItem("all"); QListIterator iter(*devices); int found = -1; int numItems = 1; while (iter.hasNext()) { InputDevice *device = iter.next(); ui->devicesComboBox->addItem(device->getSDLName(), QVariant::fromValue(device)); if (device->getUniqueIDString() == info->getUniqueID()) found = numItems; numItems++; } if (!info->getUniqueID().isEmpty() && (info->getUniqueID() != "all")) { if (found >= 0) { ui->devicesComboBox->setCurrentIndex(found); } else { ui->devicesComboBox->addItem(tr("Current (%1)").arg(info->getDeviceName())); ui->devicesComboBox->setCurrentIndex(ui->devicesComboBox->count() - 1); } } ui->profileLineEdit->setText(info->getProfileLocation()); ui->applicationLineEdit->setText(info->getExe()); ui->winClassLineEdit->setText(info->getWindowClass()); ui->winNameLineEdit->setText(info->getWindowName()); #ifdef Q_OS_UNIX ui->selectWindowPushButton->setVisible(false); #elif defined(Q_OS_WIN) ui->detectWinPropsSelectWindowPushButton->setVisible(false); ui->winClassLineEdit->setVisible(false); ui->winClassLabel->setVisible(false); // ui->winNameLineEdit->setVisible(false); // ui->winNameLabel->setVisible(false); #endif ui->asDefaultCheckBox->setEnabled(info->isCurrentDefault()); connect(ui->profileBrowsePushButton, &QPushButton::clicked, this, &AddEditAutoProfileDialog::openProfileBrowseDialog); connect(ui->applicationPushButton, &QPushButton::clicked, this, &AddEditAutoProfileDialog::openApplicationBrowseDialog); connect(ui->devicesComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AddEditAutoProfileDialog::checkForReservedUniques); connect(ui->devicesComboBox, static_cast(&QComboBox::currentTextChanged), this, &AddEditAutoProfileDialog::checkDefaultCheckbox); connect(ui->applicationLineEdit, &QLineEdit::textChanged, this, &AddEditAutoProfileDialog::checkForDefaultStatus); connect(ui->winClassLineEdit, &QLineEdit::textChanged, this, &AddEditAutoProfileDialog::checkForDefaultStatus); connect(ui->winNameLineEdit, &QLineEdit::textChanged, this, &AddEditAutoProfileDialog::checkForDefaultStatus); #if defined(Q_OS_UNIX) connect(ui->detectWinPropsSelectWindowPushButton, &QPushButton::clicked, this, &AddEditAutoProfileDialog::showCaptureHelpWindow); #elif defined(Q_OS_WIN) connect(ui->selectWindowPushButton, &QPushButton::clicked, this, &AddEditAutoProfileDialog::openWinAppProfileDialog); #endif connect(this, &AddEditAutoProfileDialog::accepted, this, &AddEditAutoProfileDialog::saveAutoProfileInformation); ui->asDefaultCheckBox->setChecked(info->isCurrentDefault()); } // created for tests AddEditAutoProfileDialog::AddEditAutoProfileDialog(QWidget *parent) : QDialog(parent) , ui(new Ui::AddEditAutoProfileDialog) { } AddEditAutoProfileDialog::~AddEditAutoProfileDialog() { delete ui; } void AddEditAutoProfileDialog::openProfileBrowseDialog() { QString lookupDir = PadderCommon::preferredProfileDir(settings); QString filename = QFileDialog::getOpenFileName(this, tr("Open Config"), lookupDir, QString("Config Files (*.amgp *.xml)")); if (!filename.isNull() && !filename.isEmpty()) ui->profileLineEdit->setText(QDir::toNativeSeparators(filename)); } void AddEditAutoProfileDialog::openApplicationBrowseDialog() { #ifdef Q_OS_WIN QString filename = QFileDialog::getOpenFileName(this, tr("Select Program"), QDir::homePath(), tr("Programs (*.exe)")); #else QString filename = QFileDialog::getOpenFileName(this, tr("Select Program"), QDir::homePath(), QString()); #endif if (!filename.isNull() && !filename.isEmpty()) { QFileInfo exe(filename); if (exe.exists() && exe.isExecutable()) ui->applicationLineEdit->setText(filename); } } AutoProfileInfo *AddEditAutoProfileDialog::getAutoProfile() const { return info; } void AddEditAutoProfileDialog::saveAutoProfileInformation() { info->setProfileLocation(ui->profileLineEdit->text()); int deviceIndex = ui->devicesComboBox->currentIndex(); if (deviceIndex > 0) { // Assume that if the following is not true, the GUID should // not be changed. if (!ui->devicesComboBox->itemData(deviceIndex, Qt::UserRole).isNull()) { InputDevice *device = ui->devicesComboBox->itemData(deviceIndex, Qt::UserRole).value(); info->setUniqueID(device->getUniqueIDString()); info->setDeviceName(device->getSDLName()); } } else { info->setUniqueID("all"); info->setDeviceName(""); } info->setExe(ui->applicationLineEdit->text()); info->setWindowClass(ui->winClassLineEdit->text()); info->setWindowName(ui->winNameLineEdit->text()); info->setDefaultState(ui->asDefaultCheckBox->isChecked()); info->setPartialState(ui->setPartialCheckBox->isChecked()); } void AddEditAutoProfileDialog::checkForReservedUniques(int index) { QVariant data = ui->devicesComboBox->itemData(index); if (index == 0) { ui->asDefaultCheckBox->setChecked(false); ui->asDefaultCheckBox->setEnabled(false); QMessageBox::warning(this, tr("Main Profile"), tr("Please use the main default profile selection.")); } else if (!data.isNull() && getReservedUniques().contains(data.value()->getUniqueIDString())) { ui->asDefaultCheckBox->setChecked(false); ui->asDefaultCheckBox->setEnabled(false); QMessageBox::warning(this, tr("Already selected"), tr("A different profile is already selected as the default for this device.")); } else { ui->asDefaultCheckBox->setEnabled(true); QMessageBox::information(this, tr("Chosen Profile"), tr("The selection will be used instead\nof the all default profile option.")); } } QString AddEditAutoProfileDialog::getOriginalUniqueID() const { return originalUniqueID; } QString AddEditAutoProfileDialog::getOriginalExe() const { return originalExe; } QString AddEditAutoProfileDialog::getOriginalWindowClass() const { return originalWindowClass; } QString AddEditAutoProfileDialog::getOriginalWindowName() const { return originalWindowName; } #ifdef Q_OS_UNIX /** * @brief Display a simple message box and attempt to capture a window using the mouse */ void AddEditAutoProfileDialog::showCaptureHelpWindow() { #ifdef WITH_X11 if (QApplication::platformName() == QStringLiteral("xcb")) { QMessageBox *box = new QMessageBox(this); box->setText(tr("Please select a window by using the mouse. Press Escape if you want to cancel.")); box->setWindowTitle(tr("Capture Application Window")); box->setStandardButtons(QMessageBox::NoButton); box->setModal(true); box->show(); UnixCaptureWindowUtility *util = new UnixCaptureWindowUtility(); QThread *capture_window_thr = new QThread; // QTHREAD(this) capture_window_thr->setObjectName("capture_window_thr"); util->moveToThread(capture_window_thr); connect(capture_window_thr, &QThread::started, util, &UnixCaptureWindowUtility::attemptWindowCapture); connect(util, &UnixCaptureWindowUtility::captureFinished, capture_window_thr, &QThread::quit); connect(util, &UnixCaptureWindowUtility::captureFinished, box, &QMessageBox::hide); connect( util, &UnixCaptureWindowUtility::captureFinished, this, [this, util]() { checkForGrabbedWindow(util); }, Qt::QueuedConnection); connect(capture_window_thr, &QThread::finished, box, &QMessageBox::deleteLater); connect(util, &UnixCaptureWindowUtility::destroyed, capture_window_thr, &QThread::deleteLater); capture_window_thr->start(); } #endif } /** * @brief Check if there is a program path saved in an UnixCaptureWindowUtility * object */ void AddEditAutoProfileDialog::checkForGrabbedWindow(UnixCaptureWindowUtility *util) { #ifdef WITH_X11 if (QApplication::platformName() == QStringLiteral("xcb")) { long targetWindow = util->getTargetWindow(); bool escaped = !util->hasFailed(); bool failed = false; if (targetWindow != None) { // Attempt to find the appropriate window below the root window // that was clicked. qDebug() << "ORIGINAL: " << QString::number(targetWindow, 16); long tempWindow = X11Extras::getInstance()->findClientWindow(targetWindow); if (tempWindow > 0) { targetWindow = tempWindow; } qDebug() << "ADJUSTED: " << QString::number(targetWindow, 16); } if (targetWindow != None) { CapturedWindowInfoDialog *dialog = new CapturedWindowInfoDialog(targetWindow, this); connect(dialog, &CapturedWindowInfoDialog::accepted, [this, dialog]() { windowPropAssignment(dialog); }); dialog->show(); } else if (!escaped) { failed = true; } // Ensure that the operation was not cancelled (Escape wasn't pressed). if (failed) { QMessageBox box; box.setText(tr("Could not obtain information for the selected window.")); box.setWindowTitle(tr("Application Capture Failed")); box.setStandardButtons(QMessageBox::Close); box.raise(); box.exec(); } util->deleteLater(); } #endif } #endif void AddEditAutoProfileDialog::windowPropAssignment(CapturedWindowInfoDialog *dialog) { disconnect(ui->applicationLineEdit, &QLineEdit::textChanged, this, &AddEditAutoProfileDialog::checkForDefaultStatus); disconnect(ui->winClassLineEdit, &QLineEdit::textChanged, this, &AddEditAutoProfileDialog::checkForDefaultStatus); disconnect(ui->winNameLineEdit, &QLineEdit::textChanged, this, &AddEditAutoProfileDialog::checkForDefaultStatus); ui->applicationLineEdit->clear(); ui->winClassLineEdit->clear(); ui->winNameLineEdit->clear(); #ifdef WITH_X11 if (dialog->useFullWindowPath() && dialog->getSelectedOptions() & CapturedWindowInfoDialog::WindowPath) { ui->applicationLineEdit->setText(dialog->getWindowPath()); } else if (!dialog->useFullWindowPath() && dialog->getSelectedOptions() & CapturedWindowInfoDialog::WindowPath) { ui->applicationLineEdit->setText(QFileInfo(dialog->getWindowPath()).fileName()); } if (dialog->getSelectedOptions() & CapturedWindowInfoDialog::WindowClass) { ui->winClassLineEdit->setText(dialog->getWindowClass()); } if (dialog->getSelectedOptions() & CapturedWindowInfoDialog::WindowName) { ui->winNameLineEdit->setText(dialog->getWindowName()); } #endif checkForDefaultStatus(); connect(ui->applicationLineEdit, &QLineEdit::textChanged, this, &AddEditAutoProfileDialog::checkForDefaultStatus); connect(ui->winClassLineEdit, &QLineEdit::textChanged, this, &AddEditAutoProfileDialog::checkForDefaultStatus); connect(ui->winNameLineEdit, &QLineEdit::textChanged, this, &AddEditAutoProfileDialog::checkForDefaultStatus); } void AddEditAutoProfileDialog::checkForDefaultStatus() { bool status = ui->applicationLineEdit->text().length() > 0; status = status ? status : (ui->winClassLineEdit->text().length() > 0); status = status ? status : (ui->winNameLineEdit->text().length() > 0); if (status) { ui->asDefaultCheckBox->setChecked(false); ui->asDefaultCheckBox->setEnabled(false); } else { ui->asDefaultCheckBox->setEnabled(true); } } /** * @throw std::runtime_error */ void AddEditAutoProfileDialog::check_profile_file() { if (ui->profileLineEdit->text().length() > 0) { QFileInfo profileFileName(ui->profileLineEdit->text()); if (!profileFileName.exists()) { throw std::runtime_error(tr("Profile file path is invalid.").toStdString()); } } } /** * @throw std::runtime_error */ void AddEditAutoProfileDialog::check_executable_file() { if (!ui->applicationLineEdit->text().isEmpty()) { QString exeFileName = ui->applicationLineEdit->text(); QFileInfo info(exeFileName); if (info.isAbsolute() && (!info.exists() || !info.isExecutable())) { throw std::runtime_error(tr("Program path is invalid or not executable.").toStdString()); } #ifdef Q_OS_WIN else if (!info.isAbsolute() && (info.fileName() != exeFileName || info.suffix() != "exe")) { throw std::runtime_error(tr("File is not an .exe file.").toStdString()); } #endif } } /** * @brief Validate the form that is contained in this window */ void AddEditAutoProfileDialog::accept() { QString errorString = QString(); try { check_profile_file(); bool is_window_specified = !(ui->applicationLineEdit->text().isEmpty() && ui->winClassLineEdit->text().isEmpty() && ui->winNameLineEdit->text().isEmpty()); if (!is_window_specified && !ui->asDefaultCheckBox->isChecked()) throw std::runtime_error(tr("No window matching property was specified.").toStdString()); check_executable_file(); } catch (const std::runtime_error &e) { QMessageBox msgBox; msgBox.setText(e.what()); msgBox.setStandardButtons(QMessageBox::Close); msgBox.exec(); } QDialog::accept(); } QList *AddEditAutoProfileDialog::getDevices() const { return devices; } AntiMicroSettings *AddEditAutoProfileDialog::getSettings() const { return settings; } bool AddEditAutoProfileDialog::getEditForm() const { return editForm; } bool AddEditAutoProfileDialog::getDefaultInfo() const { return defaultInfo; } QList const &AddEditAutoProfileDialog::getReservedUniques() { return reservedUniques; } void AddEditAutoProfileDialog::checkDefaultCheckbox(const QString &text) { if (text == "all") { ui->asDefaultCheckBox->setChecked(false); ui->asDefaultCheckBox->setDisabled(true); } else { ui->asDefaultCheckBox->setDisabled(false); } } #ifdef Q_OS_WIN void AddEditAutoProfileDialog::openWinAppProfileDialog() { WinAppProfileTimerDialog *dialog = new WinAppProfileTimerDialog(this); connect(dialog, &WinAppProfileTimerDialog::accepted, this, &AddEditAutoProfileDialog::captureWindowsApplicationPath); dialog->show(); } void AddEditAutoProfileDialog::callWindowPropAssignment() { windowPropAssignment(m_capture_window_info_dialog); } void AddEditAutoProfileDialog::captureWindowsApplicationPath() { m_capture_window_info_dialog = new CapturedWindowInfoDialog(this); connect(m_capture_window_info_dialog, &CapturedWindowInfoDialog::accepted, this, &AddEditAutoProfileDialog::callWindowPropAssignment); m_capture_window_info_dialog->show(); } #endif AntiMicroX-antimicrox-b300273/src/gui/addeditautoprofiledialog.h000066400000000000000000000061421471077622000247310ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ADDEDITAUTOPROFILEDIALOG_H #define ADDEDITAUTOPROFILEDIALOG_H #include #if defined(Q_OS_WIN) #include "capturedwindowinfodialog.h" #endif class AutoProfileInfo; class AntiMicroSettings; class InputDevice; class CapturedWindowInfoDialog; class UnixCaptureWindowUtility; namespace Ui { class AddEditAutoProfileDialog; } class AddEditAutoProfileDialog : public QDialog { Q_OBJECT public: explicit AddEditAutoProfileDialog(AutoProfileInfo *info, AntiMicroSettings *settings, QList *devices, QList &reservedUniques, bool edit = false, QWidget *parent = nullptr); AddEditAutoProfileDialog(QWidget *parent = nullptr); ~AddEditAutoProfileDialog(); AutoProfileInfo *getAutoProfile() const; QString getOriginalUniqueID() const; QString getOriginalExe() const; QString getOriginalWindowClass() const; QString getOriginalWindowName() const; QList *getDevices() const; AntiMicroSettings *getSettings() const; bool getEditForm() const; bool getDefaultInfo() const; QList const &getReservedUniques(); protected: virtual void accept(); signals: void captureFinished(); private slots: void openProfileBrowseDialog(); void openApplicationBrowseDialog(); void saveAutoProfileInformation(); void checkForReservedUniques(int index); void checkForDefaultStatus(); void windowPropAssignment(CapturedWindowInfoDialog *dialog); void checkDefaultCheckbox(const QString &text); #ifdef Q_OS_WIN void openWinAppProfileDialog(); void callWindowPropAssignment(); void captureWindowsApplicationPath(); #else void showCaptureHelpWindow(); void checkForGrabbedWindow(UnixCaptureWindowUtility *util); #endif private: Ui::AddEditAutoProfileDialog *ui; AutoProfileInfo *info; QList *devices; AntiMicroSettings *settings; bool editForm; bool defaultInfo; QList reservedUniques; QString originalUniqueID; QString originalExe; QString originalWindowClass; QString originalWindowName; #ifdef Q_OS_WIN CapturedWindowInfoDialog *m_capture_window_info_dialog; #endif void check_profile_file(); void check_executable_file(); }; #endif // ADDEDITAUTOPROFILEDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/addeditautoprofiledialog.ui000066400000000000000000000150611471077622000251170ustar00rootroot00000000000000 AddEditAutoProfileDialog 0 0 478 461 Auto Profile Dialog true Pro&file: profileLineEdit Browse Window: false false 6 4 Select Window. Click on the appropriate application window and the application file path will be populated in the form. Detect Window Properties &Class: applicationLineEdit T&itle: applicationLineEdit set partial title Application: applicationLineEdit Browse Select Window. Click on the appropriate application window and the application file path will be populated in the form. Select De&vices: devicesComboBox false Select this profile to be the default loaded for the specified device. The selection will be used instead of the all default profile option. Set as Default for Controller Qt::Horizontal Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() AddEditAutoProfileDialog accept() 254 401 157 274 buttonBox rejected() AddEditAutoProfileDialog reject() 322 401 286 274 AntiMicroX-antimicrox-b300273/src/gui/advancebuttondialog.cpp000066400000000000000000001733041471077622000242560ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "advancebuttondialog.h" #include "ui_advancebuttondialog.h" #include "event.h" #include "globalvariables.h" #include "inputdevice.h" #include "joybuttontypes/joybutton.h" #include "joytabwidget.h" #include "simplekeygrabberbutton.h" //#include "logger.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include AdvanceButtonDialog::AdvanceButtonDialog(JoyButton *button, QWidget *parent) : QDialog(parent, Qt::Window) , ui(new Ui::AdvanceButtonDialog) , helper(button) { ui->setupUi(this); ui->stackedWidget->setCurrentWidget(ui->page); setAttribute(Qt::WA_DeleteOnClose); PadderCommon::inputDaemonMutex.lock(); // ui->splitSlotButton->hide(); m_button = button; oldRow = 0; int interval = m_button->getTurboInterval() / 10; getHelperLocal().moveToThread(button->thread()); if (m_button->getToggleState()) ui->toggleCheckbox->setChecked(true); if (m_button->isUsingTurbo()) { ui->turboCheckbox->setChecked(true); ui->turboSlider->setEnabled(true); } if (interval < GlobalVariables::AdvanceButtonDialog::MINIMUMTURBO) interval = GlobalVariables::JoyButton::ENABLEDTURBODEFAULT / 10; ui->turboSlider->setValue(interval); this->changeTurboText(interval); QListIterator iter(*(m_button->getAssignedSlots())); while (iter.hasNext()) { JoyButtonSlot *buttonslot = iter.next(); qDebug() << "slot string for grab btn is: " << buttonslot->getSlotString(); SimpleKeyGrabberButton *existingCode = new SimpleKeyGrabberButton(this); existingCode->setText(buttonslot->getSlotString()); switch (static_cast(buttonslot->getSlotMode())) { case 11: if (!buttonslot->getTextData().isEmpty()) { existingCode->setValue(buttonslot->getTextData(), JoyButtonSlot::JoyLoadProfile); existingCode->setToolTip(buttonslot->getTextData()); } break; case 13: if (!buttonslot->getTextData().isEmpty()) { existingCode->setValue(buttonslot->getTextData(), JoyButtonSlot::JoyTextEntry); existingCode->setToolTip(buttonslot->getTextData()); } break; case 14: if (!buttonslot->getTextData().isEmpty()) { existingCode->setValue(buttonslot->getTextData(), JoyButtonSlot::JoyExecute); existingCode->setToolTip(buttonslot->getTextData()); if (buttonslot->getExtraData().canConvert()) existingCode->getValue()->setExtraData(buttonslot->getExtraData().toString()); } break; // JoyMix case 15: qDebug() << "text data for joy mix is: " << buttonslot->getTextData(); qDebug() << "slot string for joy mix is: " << buttonslot->getSlotString(); qDebug() << "amount of mini slots: " << buttonslot->getMixSlots()->count(); if (!buttonslot->getTextData().isEmpty()) { existingCode->setValues(buttonslot->getTextData(), buttonslot->getMixSlots(), JoyButtonSlot::JoySlotInputAction::JoyMix); existingCode->setToolTip(buttonslot->getTextData()); // try again if (existingCode->text() == tr("[NO KEY]")) { existingCode->setValues(buttonslot->getTextData(), buttonslot->getMixSlots(), JoyButtonSlot::JoySlotInputAction::JoyMix); existingCode->setToolTip(buttonslot->getTextData()); existingCode->setText(buttonslot->getSlotString()); } qDebug() << "Existing code for Joy Mix: " << existingCode->text(); } break; default: existingCode->setValue(buttonslot->getSlotCode(), buttonslot->getSlotCodeAlias(), buttonslot->getSlotMode()); break; } QListWidgetItem *item = new QListWidgetItem(ui->slotListWidget); item->setData(Qt::UserRole, QVariant::fromValue(existingCode)); QHBoxLayout *layout = new QHBoxLayout(); layout->setContentsMargins(10, 0, 10, 0); layout->addWidget(existingCode); QWidget *widget = new QWidget(); widget->setLayout(layout); item->setSizeHint(widget->sizeHint()); ui->slotListWidget->setItemWidget(item, widget); connectButtonEvents(existingCode); } appendBlankKeyGrabber(); populateSetSelectionComboBox(); populateSlotSetSelectionComboBox(); if ((m_button->getSetSelection() > -1) && (m_button->getChangeSetCondition() != JoyButton::SetChangeDisabled)) { int selectIndex = m_button->getChangeSetCondition(); selectIndex += m_button->getSetSelection() * 3; if (m_button->getOriginSet() < m_button->getSetSelection()) selectIndex -= 3; ui->setSelectionComboBox->setCurrentIndex(selectIndex); } fillTimeComboBoxes(); ui->actionTenthsComboBox->setCurrentIndex(1); updateActionTimeLabel(); changeTurboForSequences(); if (button->isCycleResetActive()) { ui->autoResetCycleCheckBox->setEnabled(true); ui->autoResetCycleCheckBox->setChecked(true); checkCycleResetWidgetStatus(true); } if (button->getCycleResetTime() != 0) populateAutoResetInterval(); updateWindowTitleButtonName(); if (m_button->isPartRealAxis() && m_button->isUsingTurbo()) { ui->turboModeComboBox->setEnabled(true); } else if (!m_button->isPartRealAxis()) { ui->turboModeComboBox->setVisible(false); ui->turboModeLabel->setVisible(false); } findTurboModeComboIndex(); // Don't show Set Selector page for modifier buttons if (m_button->isModifierButton()) delete ui->listWidget->item(3); changeSlotHelpText(ui->slotTypeComboBox->currentIndex()); PadderCommon::inputDaemonMutex.unlock(); ui->resetCycleDoubleSpinBox->setMaximum(GlobalVariables::JoyButton::MAXCYCLERESETTIME * 0.001); // static_cast connect(ui->turboCheckbox, &QCheckBox::clicked, ui->turboSlider, &QSlider::setEnabled); connect(ui->turboSlider, &QSlider::valueChanged, this, &AdvanceButtonDialog::checkTurboIntervalValue); connect(ui->insertSlotButton, &QPushButton::clicked, this, &AdvanceButtonDialog::insertSlot); connect(ui->joinSlotButton, &QPushButton::clicked, this, &AdvanceButtonDialog::joinSlot); connect(ui->splitSlotButton, &QPushButton::clicked, this, &AdvanceButtonDialog::splitSlot); connect(ui->deleteSlotButton, &QPushButton::clicked, this, &AdvanceButtonDialog::deleteSlot); connect(ui->clearAllPushButton, &QPushButton::clicked, this, &AdvanceButtonDialog::clearAllSlots); connect(ui->slotTypeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::changeSlotTypeDisplay); connect(ui->slotTypeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::changeSlotHelpText); connect(ui->actionHundredthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); connect(ui->actionSecondsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); connect(ui->actionMinutesComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); connect(ui->actionTenthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); connect(ui->toggleCheckbox, &QCheckBox::clicked, button, &JoyButton::setToggle); connect(ui->turboCheckbox, &QCheckBox::clicked, this, &AdvanceButtonDialog::checkTurboSetting); connect(ui->setSelectionComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateSetSelection); connect(ui->slotListWidget, &SlotItemListWidget::itemClicked, this, &AdvanceButtonDialog::performStatsWidgetRefresh); connect(ui->actionHundredthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); connect(ui->actionTenthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); connect(ui->actionSecondsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); connect(ui->actionMinutesComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); connect(ui->slotSetChangeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotSetChangeUpdate); connect(ui->distanceSpinBox, static_cast(&QSpinBox::valueChanged), this, &AdvanceButtonDialog::checkSlotDistanceUpdate); connect(ui->mouseSpeedModSpinBox, static_cast(&QSpinBox::valueChanged), this, &AdvanceButtonDialog::checkSlotMouseModUpdate); connect(ui->autoResetCycleCheckBox, &QCheckBox::clicked, this, &AdvanceButtonDialog::checkCycleResetWidgetStatus); connect(ui->autoResetCycleCheckBox, &QCheckBox::clicked, this, &AdvanceButtonDialog::setButtonCycleReset); connect(ui->resetCycleDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &AdvanceButtonDialog::setButtonCycleResetInterval); connect(button, &JoyButton::toggleChanged, ui->toggleCheckbox, &QCheckBox::setChecked); connect(button, &JoyButton::turboChanged, this, &AdvanceButtonDialog::checkTurboSetting); connect(ui->turboModeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::setButtonTurboMode); connect(ui->loadProfilePushButton, &QPushButton::clicked, this, &AdvanceButtonDialog::showSelectProfileWindow); connect(ui->execToolButton, &QToolButton::clicked, this, &AdvanceButtonDialog::showFindExecutableWindow); } // for tests AdvanceButtonDialog::AdvanceButtonDialog(QWidget *parent) : QDialog(parent, Qt::Window) , ui(new Ui::AdvanceButtonDialog) , helper(nullptr) { } AdvanceButtonDialog::~AdvanceButtonDialog() { delete ui; } void AdvanceButtonDialog::changeTurboText(int value) { if (value >= GlobalVariables::AdvanceButtonDialog::MINIMUMTURBO) { double delay = value / 100.0; double clicks = 100.0 / value; QString delaytext = QString::number(delay, 'g', 3).append(" ").append(tr("sec.")); QString labeltext = QString::number(clicks, 'g', 2).append(" ").append(tr("/sec.")); ui->delayValueLabel->setText(delaytext); ui->rateValueLabel->setText(labeltext); } } void AdvanceButtonDialog::updateSlotsScrollArea(int value) { int index = ui->slotListWidget->currentRow(); int itemcount = ui->slotListWidget->count(); if ((index == (itemcount - 1)) && (value >= 0)) { // New slot added on the old blank button. Append // new blank button to the end of the list. appendBlankKeyGrabber(); } // Go through all grabber buttons in list and possibly resize widgets. for (int i = 0; i < ui->slotListWidget->count(); i++) { QListWidgetItem *item = ui->slotListWidget->item(i); QWidget *widget = ui->slotListWidget->itemWidget(item); item->setSizeHint(widget->sizeHint()); } // Alter interface if turbo cannot be used. changeTurboForSequences(); emit slotsChanged(); } void AdvanceButtonDialog::connectButtonEvents(SimpleKeyGrabberButton *button) { connect(button, &SimpleKeyGrabberButton::clicked, [this, button]() { bool leave = false; for (int i = 0; (i < ui->slotListWidget->count()) && !leave; i++) { QListWidgetItem *item = ui->slotListWidget->item(i); SimpleKeyGrabberButton *tempbutton = item->data(Qt::UserRole).value(); if (button == tempbutton) { ui->slotListWidget->setCurrentRow(i); leave = true; oldRow = i; } } }); connect(button, &SimpleKeyGrabberButton::buttonCodeChanged, [this, button](int value) { JoyButtonSlot *tempbuttonslot = button->getValue(); int index = ui->slotListWidget->currentRow(); if (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoySlotInputAction::JoyMix) { QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(JoyButtonSlot *, tempbuttonslot), Q_ARG(int, index)); } else { QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, tempbuttonslot->getSlotCode()), Q_ARG(int, tempbuttonslot->getSlotCodeAlias()), Q_ARG(int, index), Q_ARG(JoyButtonSlot::JoySlotInputAction, tempbuttonslot->getSlotMode())); updateSlotsScrollArea(value); } }); } void AdvanceButtonDialog::deleteSlot(bool showWarning) { if (ui->slotListWidget->selectedItems().count() == 0) { if (showWarning) QMessageBox::warning(this, tr("Not checked slots"), tr("To delete slots, you need to select at least one")); } else { for (auto item : ui->slotListWidget->selectedItems()) { int index = ui->slotListWidget->row(item); int itemcount = ui->slotListWidget->count(); delete ui->slotListWidget->takeItem(index); // Deleted last button. Replace with new blank button if (index == (itemcount - 1)) appendBlankKeyGrabber(); changeTurboForSequences(); #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) QTimer::singleShot(0, &helper, [this, index]() { (&helper)->removeAssignedSlot(index); }); #else QMetaObject::invokeMethod(&helper, "removeAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, index)); #endif index = qMax(0, index - 1); performStatsWidgetRefresh(ui->slotListWidget->item(index)); emit slotsChanged(); } } } void AdvanceButtonDialog::appendBlankKeyGrabber() { SimpleKeyGrabberButton *blankButton = new SimpleKeyGrabberButton(this); QListWidgetItem *item = new QListWidgetItem(ui->slotListWidget); item->setData(Qt::UserRole, QVariant::fromValue(blankButton)); QHBoxLayout *layout = new QHBoxLayout(); layout->setContentsMargins(10, 0, 10, 0); layout->addWidget(blankButton); QWidget *widget = new QWidget(); widget->setLayout(layout); item->setSizeHint(widget->sizeHint()); ui->slotListWidget->setItemWidget(item, widget); ui->slotListWidget->setCurrentItem(item); connectButtonEvents(blankButton); ui->slotTypeComboBox->setCurrentIndex(static_cast(KBMouseSlot)); } void AdvanceButtonDialog::insertSlot() { if (ui->slotListWidget->selectedItems().count() == 0) { QMessageBox::warning(this, tr("Not checked slots"), tr("To insert slots, you need to select at least one")); } else { QStringList firstChoiceExec = QStringList(); QString firstChoiceProfile = QString(); for (auto item : ui->slotListWidget->selectedItems()) { int current = ui->slotListWidget->row(item); int count = ui->slotListWidget->count(); int slotTypeIndex = ui->slotTypeComboBox->currentIndex(); switch (slotTypeIndex) { case 0: if (current != (count - 1)) { SimpleKeyGrabberButton *blankButton = new SimpleKeyGrabberButton(this); QListWidgetItem *itemListWidget = new QListWidgetItem(); ui->slotListWidget->insertItem(current, itemListWidget); itemListWidget->setData(Qt::UserRole, QVariant::fromValue(blankButton)); QHBoxLayout *layout = new QHBoxLayout(); layout->addWidget(blankButton); QWidget *widget = new QWidget(); widget->setLayout(layout); itemListWidget->setSizeHint(widget->sizeHint()); ui->slotListWidget->setItemWidget(itemListWidget, widget); ui->slotListWidget->setCurrentItem(itemListWidget); connectButtonEvents(blankButton); blankButton->refreshButtonLabel(); QMetaObject::invokeMethod(&helper, "insertAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, 0), Q_ARG(int, 0), Q_ARG(int, current)); updateSlotsScrollArea(0); } break; case 1: insertCycleSlot(item); break; case 2: insertKindOfSlot(item, actionTimeConvert(), JoyButtonSlot::JoyDelay); break; case 3: insertKindOfSlot(item, ui->distanceSpinBox->value(), JoyButtonSlot::JoyDistance); break; case 4: insertExecuteSlot(item, firstChoiceExec); break; case 5: insertKindOfSlot(item, actionTimeConvert(), JoyButtonSlot::JoyHold); break; case 6: showSelectProfileWind(item, firstChoiceProfile); break; case 7: insertKindOfSlot(item, ui->mouseSpeedModSpinBox->value(), JoyButtonSlot::JoyMouseSpeedMod); break; case 8: insertKindOfSlot(item, actionTimeConvert(), JoyButtonSlot::JoyPause); break; case 9: insertKindOfSlot(item, actionTimeConvert(), JoyButtonSlot::JoyKeyPress); break; case 10: insertKindOfSlot(item, actionTimeConvert(), JoyButtonSlot::JoyRelease); break; case 11: insertKindOfSlot(item, ui->slotSetChangeComboBox->itemData(ui->slotSetChangeComboBox->currentIndex()).toInt(), JoyButtonSlot::JoySetChange); break; case 12: insertTextEntrySlot(item); break; } } } } void AdvanceButtonDialog::joinSlot() { QReadLocker tempAssignLocker(&joinLock); joinLock.lockForRead(); if (ui->slotListWidget->currentRow() == -1) { QMessageBox::warning(this, tr("Unknown current slot"), tr("Click on chosen slots before joining them")); } else if (ui->slotListWidget->count() < 3) { QMessageBox::warning(this, tr("Not enough slots"), tr("It's impossible to join slots. Add at least one other slot.")); } else if (ui->slotListWidget->selectedItems().count() < 2) { QMessageBox::warning(this, tr("Not selected slots"), tr("It's impossible to join slots. Select at least two slots before joining them")); } else if (anySelectedNotKeybSlot()) { QMessageBox::warning(this, tr("Only keyboard slots"), tr("It's only possible to join simple and mix keyboard slots")); } else { qDebug() << "Chosen " << ui->slotListWidget->selectedItems().count() << " slots"; QListWidgetItem *firstSelected = ui->slotListWidget->selectedItems().at(0); QString text = ""; int index = ui->slotListWidget->row(firstSelected); bool firstTime = true; SimpleKeyGrabberButton *blankButton = new SimpleKeyGrabberButton(this); QList listItems = ui->slotListWidget->selectedItems(); for (auto item : listItems) { if (!firstTime) text += "+"; firstTime = false; SimpleKeyGrabberButton *firstGrabBtn = item->data(Qt::UserRole).value(); if (firstGrabBtn->getValue()->getMixSlots()->count() > 0) { QList slotsList; for (auto mini : *firstGrabBtn->getValue()->getMixSlots()) slotsList.append(new JoyButtonSlot(mini->getSlotCode(), mini->getSlotCodeAlias(), mini->getSlotMode())); // Q_ASSERT(blankButton->getValue() != nullptr); blankButton->getValue()->appendMiniSlot>(slotsList); } else { JoyButtonSlot *slotmini = new JoyButtonSlot(firstGrabBtn->getValue()->getSlotCode(), firstGrabBtn->getValue()->getSlotCodeAlias(), firstGrabBtn->getValue()->getSlotMode()); // Q_ASSERT(blankButton->getValue() != nullptr); blankButton->getValue()->appendMiniSlot(slotmini); } text += firstGrabBtn->getValue()->getSlotString(); } blankButton->getValue()->setTextData(text); blankButton->getValue()->setSlotMode(JoyButtonSlot::JoyMix); blankButton->getValue()->setSlotCode(-1); deleteSlot(false); // Q_ASSERT(blankButton->getValue()->getMixSlots() != nullptr); // Q_ASSERT(blankButton->getValue()->getMixSlots()->count() > 0); for (auto x : *blankButton->getValue()->getMixSlots()) { // Q_ASSERT(x->getSlotMode() == 0); // Q_ASSERT(!x->getSlotString().isEmpty()); qDebug() << "JOINED MINI: " << x->getSlotCode() << " - " << x->getSlotMode() << " - " << x->getSlotString(); } QListWidgetItem *joinedItem = new QListWidgetItem(); ui->slotListWidget->insertItem(qMax(0, index), joinedItem); joinedItem->setData(Qt::UserRole, QVariant::fromValue(blankButton)); QHBoxLayout *layout = new QHBoxLayout(); layout->addWidget(blankButton); QWidget *widget = new QWidget(); widget->setLayout(layout); joinedItem->setSizeHint(widget->sizeHint()); ui->slotListWidget->setItemWidget(joinedItem, widget); ui->slotListWidget->setCurrentItem(joinedItem); // blankButton->setValues(text, blankButton->getValue()->getMixSlots(), JoyButtonSlot::JoyMix); connectButtonEvents(blankButton); blankButton->refreshButtonLabel(); // instead of blankButton->setText(text); QMetaObject::invokeMethod(&helper, "insertAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(JoyButtonSlot *, blankButton->getValue()), Q_ARG(int, index), Q_ARG(bool, false)); } joinLock.unlock(); } void AdvanceButtonDialog::splitSlot() { int index = ui->slotListWidget->currentRow(); if (index == -1) { QMessageBox::warning(this, tr("Unknown current slot"), tr("Click on chosen slots before joining them")); } else if (ui->slotListWidget->count() < 2) { QMessageBox::warning(this, tr("Not enough slots"), tr("It's impossible to split slots. Add at least one other slot.")); } else if (ui->slotListWidget->selectedItems().count() < 1) { QMessageBox::warning(this, tr("Not selected slot"), tr("Select your slot before splitting.")); } else if (ui->slotListWidget->selectedItems().count() > 1) { QMessageBox::warning(this, tr("Too many mix slots"), tr("Select one mix slot.")); } else if (selectedNotMixSlot()) { QMessageBox::warning(this, tr("Only mix slots"), tr("It's only possible to split mix slot.")); } else { QReadLocker tempAssignLocker(&joinLock); joinLock.lockForRead(); QListWidgetItem *mixSlot = ui->slotListWidget->selectedItems().at(0); int indexMixSlot = ui->slotListWidget->row(mixSlot); int indexKeyboardSlot = indexMixSlot; QList minislots = *mixSlot->data(Qt::UserRole).value()->getValue()->getMixSlots(); for (auto minislot : minislots) { qDebug() << "MINISLOT SPLIT NAME: " << minislot->getSlotString(); QListWidgetItem *splitItem = new QListWidgetItem(); SimpleKeyGrabberButton *blankButton = new SimpleKeyGrabberButton(this); JoyButtonSlot *slotmini = new JoyButtonSlot(minislot->getSlotCode(), minislot->getSlotCodeAlias(), minislot->getSlotMode()); ui->slotListWidget->insertItem(qMax(0, indexKeyboardSlot), splitItem); blankButton->setValue(slotmini); delete slotmini; slotmini = nullptr; splitItem->setData(Qt::UserRole, QVariant::fromValue(blankButton)); QHBoxLayout *layout = new QHBoxLayout(); layout->addWidget(blankButton); QWidget *widget = new QWidget(); widget->setLayout(layout); splitItem->setSizeHint(widget->sizeHint()); ui->slotListWidget->setItemWidget(splitItem, widget); // ui->slotListWidget->setCurrentItem(splitItem); connectButtonEvents(blankButton); blankButton->refreshButtonLabel(); // instead of blankButton->setText(text); QMetaObject::invokeMethod(&helper, "insertAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, blankButton->getValue()->getSlotCode()), Q_ARG(int, blankButton->getValue()->getSlotCodeAlias()), Q_ARG(int, indexKeyboardSlot), Q_ARG(JoyButtonSlot::JoySlotInputAction, blankButton->getValue()->getSlotMode())); indexKeyboardSlot++; } // it can be used as reusable code deleteSlot(false); joinLock.unlock(); } } void AdvanceButtonDialog::insertKindOfSlot(QListWidgetItem *item, int slotProperty, JoyButtonSlot::JoySlotInputAction inputAction) { int index = ui->slotListWidget->row(item); int actionTime = slotProperty; SimpleKeyGrabberButton *tempbutton = item->data(Qt::UserRole).value(); int tempDistance = 0; bool slotPropertyAboveLimit = actionTime >= 0; if (inputAction == JoyButtonSlot::JoyDistance) { for (int i = 0; i < ui->slotListWidget->count(); i++) { SimpleKeyGrabberButton *button = ui->slotListWidget->item(i)->data(Qt::UserRole).value(); JoyButtonSlot *tempbuttonslot = button->getValue(); if (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyDistance) { tempDistance += tempbuttonslot->getSlotCode(); } else if (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyCycle) { tempDistance = 0; } } tempDistance += actionTime; slotPropertyAboveLimit = tempDistance <= 100; } if (slotPropertyAboveLimit) { tempbutton->setValue(actionTime, inputAction); QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, actionTime), Q_ARG(int, 0), Q_ARG(int, index), Q_ARG(JoyButtonSlot::JoySlotInputAction, inputAction)); updateSlotsScrollArea(actionTime); } } int AdvanceButtonDialog::actionTimeConvert() { int tempMilliSeconds = ui->actionMinutesComboBox->currentIndex() * 1000 * 60; tempMilliSeconds += ui->actionSecondsComboBox->currentIndex() * 1000; tempMilliSeconds += ui->actionTenthsComboBox->currentIndex() * 100; tempMilliSeconds += ui->actionHundredthsComboBox->currentIndex() * 10; return tempMilliSeconds; } void AdvanceButtonDialog::refreshTimeComboBoxes(JoyButtonSlot *slot) { disconnectTimeBoxesEvents(); int slottime = slot->getSlotCode(); ui->actionMinutesComboBox->setCurrentIndex(slottime / 1000 / 60); ui->actionSecondsComboBox->setCurrentIndex(slottime / 1000 % 60); ui->actionTenthsComboBox->setCurrentIndex((slottime % 1000) / 100); ui->actionHundredthsComboBox->setCurrentIndex((slottime % 1000 % 100) / 10); updateActionTimeLabel(); connectTimeBoxesEvents(); } void AdvanceButtonDialog::updateActionTimeLabel() { int actionTime = actionTimeConvert(); int minutes = actionTime / 1000 / 60; double hundredths = actionTime % 1000 / 1000.0; double seconds = (actionTime / 1000 % 60) + hundredths; QString actionTimeLabel = QString(); actionTimeLabel.append(QString::number(minutes)).append("m "); actionTimeLabel.append(QString::number(seconds, 'f', 2)).append("s"); ui->actionTimeLabel->setText(actionTimeLabel); } void AdvanceButtonDialog::clearAllSlots() { ui->slotListWidget->clear(); appendBlankKeyGrabber(); changeTurboForSequences(); QMetaObject::invokeMethod(m_button, "clearSlotsEventReset", Qt::BlockingQueuedConnection); performStatsWidgetRefresh(ui->slotListWidget->currentItem()); emit slotsChanged(); } void AdvanceButtonDialog::changeTurboForSequences() { bool containsSequences = false; for (int i = 0; (i < ui->slotListWidget->count()) && !containsSequences; i++) { SimpleKeyGrabberButton *button = ui->slotListWidget->item(i)->data(Qt::UserRole).value(); JoyButtonSlot *tempbuttonslot = button->getValue(); if ((tempbuttonslot->getSlotCode() > 0) && ((tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyPause) || (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyHold) || (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyDistance))) { containsSequences = true; } } if (containsSequences) { if (ui->turboCheckbox->isChecked()) { ui->turboCheckbox->setChecked(false); m_button->setUseTurbo(false); emit turboChanged(false); } if (ui->turboCheckbox->isEnabled()) { ui->turboCheckbox->setEnabled(false); emit turboButtonEnabledChange(false); } } else if (!ui->turboCheckbox->isEnabled()) { ui->turboCheckbox->setEnabled(true); emit turboButtonEnabledChange(true); } } void AdvanceButtonDialog::insertCycleSlot(QListWidgetItem *item) { int index = ui->slotListWidget->row(item); SimpleKeyGrabberButton *tempbutton = item->data(Qt::UserRole).value(); tempbutton->setValue(1, JoyButtonSlot::JoyCycle); QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, 1), Q_ARG(int, 0), Q_ARG(int, index), Q_ARG(JoyButtonSlot::JoySlotInputAction, JoyButtonSlot::JoyCycle)); updateSlotsScrollArea(1); } void AdvanceButtonDialog::placeNewSlot(JoyButtonSlot *slot) { int index = ui->slotListWidget->currentRow(); SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem()->data(Qt::UserRole).value(); tempbutton->setValue(slot->getSlotCode(), slot->getSlotCodeAlias(), slot->getSlotMode()); QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, slot->getSlotCode()), Q_ARG(int, slot->getSlotCodeAlias()), Q_ARG(int, index), Q_ARG(JoyButtonSlot::JoySlotInputAction, slot->getSlotMode())); updateSlotsScrollArea(slot->getSlotCode()); slot->deleteLater(); } void AdvanceButtonDialog::updateTurboIntervalValue(int value) { if (value >= GlobalVariables::AdvanceButtonDialog::MINIMUMTURBO) { m_button->setTurboInterval(value * 10); } } void AdvanceButtonDialog::checkTurboSetting(bool state) { ui->turboCheckbox->setChecked(state); ui->turboSlider->setEnabled(state); if (m_button->isPartRealAxis()) ui->turboModeComboBox->setEnabled(state); changeTurboForSequences(); m_button->setUseTurbo(state); if ((m_button->getTurboInterval() / 10) >= GlobalVariables::AdvanceButtonDialog::MINIMUMTURBO) { ui->turboSlider->setValue(m_button->getTurboInterval() / 10); } } void AdvanceButtonDialog::updateSetSelection() { PadderCommon::inputDaemonMutex.lock(); int chosen_set; JoyButton::SetChangeCondition set_selection_condition = JoyButton::SetChangeDisabled; if (ui->setSelectionComboBox->currentIndex() > 0) { int condition_choice = (ui->setSelectionComboBox->currentIndex() + 2) % 3; chosen_set = (ui->setSelectionComboBox->currentIndex() - 1) / 3; if (m_button->getOriginSet() > chosen_set) // Above removed rows { chosen_set = (ui->setSelectionComboBox->currentIndex() - 1) / 3; } else // Below removed rows { chosen_set = (ui->setSelectionComboBox->currentIndex() + 2) / 3; } qDebug() << "CONDITION: " << QString::number(condition_choice); switch (condition_choice) { case 0: set_selection_condition = JoyButton::SetChangeOneWay; break; case 1: set_selection_condition = JoyButton::SetChangeTwoWay; break; case 2: set_selection_condition = JoyButton::SetChangeWhileHeld; break; } qDebug() << "CHOSEN SET: " << chosen_set; } else { chosen_set = -1; set_selection_condition = JoyButton::SetChangeDisabled; } if ((chosen_set > -1) && (set_selection_condition != JoyButton::SetChangeDisabled)) { // First, remove old condition for the button in both sets. // After that, make the new assignment. m_button->setChangeSetCondition(JoyButton::SetChangeDisabled); m_button->setChangeSetSelection(chosen_set); m_button->setChangeSetCondition(set_selection_condition); } else { m_button->setChangeSetCondition(JoyButton::SetChangeDisabled); } PadderCommon::inputDaemonMutex.unlock(); } void AdvanceButtonDialog::checkTurboIntervalValue(int value) { if (value >= GlobalVariables::AdvanceButtonDialog::MINIMUMTURBO) { changeTurboText(value); updateTurboIntervalValue(value); } else { ui->turboSlider->setValue(GlobalVariables::AdvanceButtonDialog::MINIMUMTURBO); } } void AdvanceButtonDialog::fillTimeComboBoxes() { ui->actionMinutesComboBox->clear(); ui->actionSecondsComboBox->clear(); ui->actionHundredthsComboBox->clear(); ui->actionTenthsComboBox->clear(); for (int i = 0; i <= 10; i++) { QString minText = QString::number(i, 'g', 2).append("m"); ui->actionMinutesComboBox->addItem(minText); } for (int i = 0; i <= 59; i++) { QString secsText = QString::number(i, 'g', 2); ui->actionSecondsComboBox->addItem(secsText); } for (int i = 0; i < 10; i++) { QString tenthsText = QString(".%1").arg(i, 1, 10, QChar('0')); ui->actionTenthsComboBox->addItem(tenthsText); } for (int i = 0; i < 10; i++) { QString hundrText = QString("%1s").arg(i, 1, 10, QChar('0')); ui->actionHundredthsComboBox->addItem(hundrText); } } void AdvanceButtonDialog::insertTextEntrySlot(QListWidgetItem *item) { int index = ui->slotListWidget->row(item); QString entryText = ui->textEntryLineEdit->text(); SimpleKeyGrabberButton *textEntryButton = item->data(Qt::UserRole).value(); if (!entryText.isEmpty()) { textEntryButton->setValue(entryText, JoyButtonSlot::JoyTextEntry); QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(JoyButtonSlot *, textEntryButton->getValue()), Q_ARG(int, index)); textEntryButton->setToolTip(entryText); updateSlotsScrollArea(0); } } void AdvanceButtonDialog::insertExecuteSlot(QListWidgetItem *item, QStringList &prevExecAndArgs) { int index = ui->slotListWidget->row(item); QString execSlotName, argsExecSlot; QFile execFile; QFileInfo execSlotNameInfo; if (prevExecAndArgs.empty()) // the first time when we choose script { execSlotName = ui->execLineEdit->text(); argsExecSlot = ui->execArgumentsLineEdit->text(); } else // when we want to apply changes to many slots at once { execSlotName = prevExecAndArgs.first(); if (prevExecAndArgs.length() == 2) argsExecSlot = prevExecAndArgs.last(); } execFile.setFileName(execSlotName); execSlotNameInfo.setFile(execSlotName); SimpleKeyGrabberButton *execbutton = item->data(Qt::UserRole).value(); if (execSlotName.isEmpty()) QMessageBox::warning( this, tr("Empty execution path"), tr("Line for execution file path is empty. Fill the first line before you are going to add a slot.")); else if (!execSlotNameInfo.exists()) QMessageBox::warning(this, tr("File doesn't exist"), tr("There is no such file locally, that could be executed. Check the file on your system")); else { prevExecAndArgs.clear(); execbutton->setValue(execSlotName, JoyButtonSlot::JoyExecute); prevExecAndArgs << execSlotName; if (!argsExecSlot.isEmpty()) { execbutton->getValue()->setExtraData(QVariant(argsExecSlot)); prevExecAndArgs << argsExecSlot; } QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(JoyButtonSlot *, execbutton->getValue()), Q_ARG(int, index)); execbutton->setToolTip(execSlotName); updateSlotsScrollArea(0); } } void AdvanceButtonDialog::performStatsWidgetRefresh(QListWidgetItem *item) { SimpleKeyGrabberButton *button = item->data(Qt::UserRole).value(); JoyButtonSlot *slot = button->getValue(); if ((slot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (slot->getSlotCode() != 0)) { ui->slotTypeComboBox->setCurrentIndex(0); } else if ((slot->getSlotMode() == JoyButtonSlot::JoyMouseButton) || (slot->getSlotMode() == JoyButtonSlot::JoyMouseMovement)) { ui->slotTypeComboBox->setCurrentIndex(0); } else if (slot->getSlotMode() == JoyButtonSlot::JoyCycle) { ui->slotTypeComboBox->setCurrentIndex(1); } else if (slot->getSlotMode() == JoyButtonSlot::JoyDelay) { ui->slotTypeComboBox->setCurrentIndex(2); refreshTimeComboBoxes(slot); } else if (slot->getSlotMode() == JoyButtonSlot::JoyDistance) { ui->slotTypeComboBox->setCurrentIndex(3); disconnect(ui->distanceSpinBox, static_cast(&QSpinBox::valueChanged), this, &AdvanceButtonDialog::checkSlotDistanceUpdate); ui->distanceSpinBox->setValue(slot->getSlotCode()); connect(ui->distanceSpinBox, static_cast(&QSpinBox::valueChanged), this, &AdvanceButtonDialog::checkSlotDistanceUpdate); } else if (slot->getSlotMode() == JoyButtonSlot::JoyHold) { ui->slotTypeComboBox->setCurrentIndex(5); refreshTimeComboBoxes(slot); } else if (slot->getSlotMode() == JoyButtonSlot::JoyLoadProfile) { ui->slotTypeComboBox->setCurrentIndex(6); } else if (slot->getSlotMode() == JoyButtonSlot::JoyMouseSpeedMod) { ui->slotTypeComboBox->setCurrentIndex(7); disconnect(ui->mouseSpeedModSpinBox, static_cast(&QSpinBox::valueChanged), this, &AdvanceButtonDialog::checkSlotMouseModUpdate); ui->mouseSpeedModSpinBox->setValue(slot->getSlotCode()); connect(ui->mouseSpeedModSpinBox, static_cast(&QSpinBox::valueChanged), this, &AdvanceButtonDialog::checkSlotMouseModUpdate); } else if (slot->getSlotMode() == JoyButtonSlot::JoyPause) { ui->slotTypeComboBox->setCurrentIndex(8); refreshTimeComboBoxes(slot); } else if (slot->getSlotMode() == JoyButtonSlot::JoyKeyPress) { ui->slotTypeComboBox->setCurrentIndex(9); refreshTimeComboBoxes(slot); } else if (slot->getSlotMode() == JoyButtonSlot::JoyRelease) { ui->slotTypeComboBox->setCurrentIndex(10); refreshTimeComboBoxes(slot); } else if (slot->getSlotMode() == JoyButtonSlot::JoySetChange) { disconnect(ui->slotSetChangeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotSetChangeUpdate); ui->slotTypeComboBox->setCurrentIndex(11); int chooseIndex = slot->getSlotCode(); int foundIndex = ui->slotSetChangeComboBox->findData(QVariant(chooseIndex)); if (foundIndex >= 0) ui->slotSetChangeComboBox->setCurrentIndex(foundIndex); connect(ui->slotSetChangeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotSetChangeUpdate); } else if (slot->getSlotMode() == JoyButtonSlot::JoyTextEntry) { ui->slotTypeComboBox->setCurrentIndex(12); ui->textEntryLineEdit->setText(slot->getTextData()); } else if (slot->getSlotMode() == JoyButtonSlot::JoyExecute) { ui->slotTypeComboBox->setCurrentIndex(4); ui->execLineEdit->setText(slot->getTextData()); ui->execArgumentsLineEdit->setText(slot->getExtraData().toString()); } } void AdvanceButtonDialog::checkSlotTimeUpdate() { int actionTime = actionTimeConvert(); int index = ui->slotListWidget->currentRow(); SimpleKeyGrabberButton *button = ui->slotListWidget->currentItem()->data(Qt::UserRole).value(); JoyButtonSlot *buttonSlot = button->getValue(); if ((buttonSlot->getSlotMode() == JoyButtonSlot::JoyPause) || (buttonSlot->getSlotMode() == JoyButtonSlot::JoyHold) || (buttonSlot->getSlotMode() == JoyButtonSlot::JoyRelease) || (buttonSlot->getSlotMode() == JoyButtonSlot::JoyKeyPress) || (buttonSlot->getSlotMode() == JoyButtonSlot::JoyDelay)) { if (actionTime > 0) { button->setValue(actionTime, buttonSlot->getSlotMode()); QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, actionTime), Q_ARG(int, 0), Q_ARG(int, index), Q_ARG(JoyButtonSlot::JoySlotInputAction, buttonSlot->getSlotMode())); updateSlotsScrollArea(actionTime); } } } void AdvanceButtonDialog::checkSlotMouseModUpdate() { int tempMouseMod = ui->mouseSpeedModSpinBox->value(); int index = ui->slotListWidget->currentRow(); SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem()->data(Qt::UserRole).value(); JoyButtonSlot *tempbuttonslot = tempbutton->getValue(); if ((tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyMouseSpeedMod) && (tempMouseMod > 0)) { tempbutton->setValue(tempMouseMod, tempbuttonslot->getSlotMode()); QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, tempMouseMod), Q_ARG(int, 0), Q_ARG(int, index), Q_ARG(JoyButtonSlot::JoySlotInputAction, tempbuttonslot->getSlotMode())); updateSlotsScrollArea(tempMouseMod); } } void AdvanceButtonDialog::checkSlotSetChangeUpdate() { int index = ui->slotListWidget->currentRow(); SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem()->data(Qt::UserRole).value(); JoyButtonSlot *buttonslot = tempbutton->getValue(); if (buttonslot->getSlotMode() == JoyButtonSlot::JoySetChange && (ui->slotSetChangeComboBox->itemData(ui->slotSetChangeComboBox->currentIndex()).toInt() >= 0)) { int comboIndex = ui->slotSetChangeComboBox->currentIndex(); int setIndex = ui->slotSetChangeComboBox->itemData(comboIndex).toInt(); tempbutton->setValue(setIndex, buttonslot->getSlotMode()); QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, setIndex), Q_ARG(int, 0), Q_ARG(int, index), Q_ARG(JoyButtonSlot::JoySlotInputAction, buttonslot->getSlotMode())); updateSlotsScrollArea(setIndex); } } void AdvanceButtonDialog::checkSlotDistanceUpdate() { int index = ui->slotListWidget->currentRow(); SimpleKeyGrabberButton *tempbutton = ui->slotListWidget->currentItem()->data(Qt::UserRole).value(); JoyButtonSlot *buttonslot = tempbutton->getValue(); if (buttonslot->getSlotMode() == JoyButtonSlot::JoyDistance) { int tempDistance = 0; for (int i = 0; i < ui->slotListWidget->count(); i++) { SimpleKeyGrabberButton *button = ui->slotListWidget->item(i)->data(Qt::UserRole).value(); JoyButtonSlot *tempbuttonslot = button->getValue(); if (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyDistance) { tempDistance += tempbuttonslot->getSlotCode(); } else if (tempbuttonslot->getSlotMode() == JoyButtonSlot::JoyCycle) { tempDistance = 0; } } int testDistance = ui->distanceSpinBox->value(); tempDistance += testDistance - buttonslot->getSlotCode(); if (tempDistance <= 100) { tempbutton->setValue(testDistance, buttonslot->getSlotMode()); QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, testDistance), Q_ARG(int, 0), Q_ARG(int, index), Q_ARG(JoyButtonSlot::JoySlotInputAction, buttonslot->getSlotMode())); updateSlotsScrollArea(testDistance); } } } void AdvanceButtonDialog::updateWindowTitleButtonName() { QString windTitleBtnName = QString().append(tr("Advanced").append(": ")).append(m_button->getPartialName(false, true)); if (m_button->getParentSet()->getIndex() != 0) { int setIndex = m_button->getParentSet()->getRealIndex(); windTitleBtnName.append(" [").append(tr("Set %1").arg(setIndex)); QString setName = m_button->getParentSet()->getName(); if (!setName.isEmpty()) windTitleBtnName.append(": ").append(setName); windTitleBtnName.append("]"); } setWindowTitle(windTitleBtnName); } void AdvanceButtonDialog::checkCycleResetWidgetStatus(bool enabled) { if (enabled) ui->resetCycleDoubleSpinBox->setEnabled(true); else ui->resetCycleDoubleSpinBox->setEnabled(false); } void AdvanceButtonDialog::setButtonCycleResetInterval(double value) { int milliseconds = value * 1000; m_button->setCycleResetTime(milliseconds); } void AdvanceButtonDialog::populateAutoResetInterval() { double seconds = m_button->getCycleResetTime() / 1000.0; ui->resetCycleDoubleSpinBox->setValue(seconds); } void AdvanceButtonDialog::setButtonCycleReset(bool enabled) { if (enabled) { m_button->setCycleResetStatus(true); if ((m_button->getCycleResetTime() == 0) && (ui->resetCycleDoubleSpinBox->value() > 0.0)) { double current = ui->resetCycleDoubleSpinBox->value(); setButtonCycleResetInterval(current); } } else { m_button->setCycleResetStatus(false); } } void AdvanceButtonDialog::resetTimeBoxes() { disconnectTimeBoxesEvents(); ui->actionMinutesComboBox->setCurrentIndex(0); ui->actionSecondsComboBox->setCurrentIndex(0); ui->actionTenthsComboBox->setCurrentIndex(1); ui->actionHundredthsComboBox->setCurrentIndex(0); updateActionTimeLabel(); connectTimeBoxesEvents(); } void AdvanceButtonDialog::disconnectTimeBoxesEvents() { disconnect(ui->actionSecondsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); disconnect(ui->actionHundredthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); disconnect(ui->actionMinutesComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); disconnect(ui->actionTenthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); disconnect(ui->actionHundredthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); disconnect(ui->actionSecondsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); disconnect(ui->actionMinutesComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); disconnect(ui->actionTenthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); } void AdvanceButtonDialog::connectTimeBoxesEvents() { connect(ui->actionSecondsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); connect(ui->actionHundredthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); connect(ui->actionMinutesComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); connect(ui->actionTenthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::updateActionTimeLabel); connect(ui->actionHundredthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); connect(ui->actionSecondsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); connect(ui->actionMinutesComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); connect(ui->actionTenthsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceButtonDialog::checkSlotTimeUpdate); } void AdvanceButtonDialog::populateSetSelectionComboBox() { ui->setSelectionComboBox->clear(); ui->setSelectionComboBox->insertItem(0, tr("Disabled")); int currentIndex = 1; for (auto set = m_button->getParentSet()->getInputDevice()->getJoystick_sets().begin(); set != m_button->getParentSet()->getInputDevice()->getJoystick_sets().end(); ++set) { int originset = set.key(); if (m_button->getOriginSet() != originset) { QString selectedSetText = QString(tr("Select Set %1").arg(originset + 1)); QString setName = set.value()->getName(); if (!setName.isEmpty()) { selectedSetText.append(" ").append("["); selectedSetText.append(setName).append("]").append(" "); } QString oneWayText = QString(selectedSetText).append(" ").append(tr("One Way")); QString twoWayText = QString(selectedSetText).append(" ").append(tr("Two Way")); QString whileHeldText = QString(selectedSetText).append(" ").append(tr("While Held")); QStringList setChoices = QStringList(); setChoices.append(oneWayText); setChoices.append(twoWayText); setChoices.append(whileHeldText); ui->setSelectionComboBox->insertItems(currentIndex, setChoices); currentIndex += 3; } originset++; } } void AdvanceButtonDialog::populateSlotSetSelectionComboBox() { ui->slotSetChangeComboBox->clear(); int current_box_index = 0; for (auto set = m_button->getParentSet()->getInputDevice()->getJoystick_sets().begin(); set != m_button->getParentSet()->getInputDevice()->getJoystick_sets().end(); ++set) { int originset = set.key(); if (m_button->getOriginSet() != originset) { QString selectedSetSlotText = QString(tr("Select Set %1").arg(originset + 1)); QString setName = set.value()->getName(); if (!setName.isEmpty()) { selectedSetSlotText.append(" ").append("["); selectedSetSlotText.append(setName).append("]").append(" "); } ui->slotSetChangeComboBox->insertItem(current_box_index, selectedSetSlotText, QVariant(originset)); current_box_index++; } originset++; } } void AdvanceButtonDialog::findTurboModeComboIndex() { JoyButton::TurboMode currentTurboMode = m_button->getTurboMode(); switch (static_cast(currentTurboMode)) { case 0: ui->turboModeComboBox->setCurrentIndex(0); break; case 1: ui->turboModeComboBox->setCurrentIndex(1); break; case 2: ui->turboModeComboBox->setCurrentIndex(2); break; } } void AdvanceButtonDialog::setButtonTurboMode(int value) { switch (value) { case 0: m_button->setTurboMode(JoyButton::NormalTurbo); break; case 1: m_button->setTurboMode(JoyButton::GradientTurbo); break; case 2: m_button->setTurboMode(JoyButton::PulseTurbo); break; } } void AdvanceButtonDialog::showSelectProfileWindow() { // It can be used as reusable code insertSlot(); } void AdvanceButtonDialog::showSelectProfileWind(QListWidgetItem *item, QString &firstChoiceProfile) { int index = ui->slotListWidget->row(item); AntiMicroSettings *settings = m_button->getParentSet()->getInputDevice()->getSettings(); QString preferredDir, profileName; if (firstChoiceProfile.size() <= 0) { preferredDir = PadderCommon::preferredProfileDir(settings); profileName = QFileDialog::getOpenFileName(this, tr("Choose Profile"), preferredDir, tr("Config Files (*.amgp *.xml)")); } else { profileName = firstChoiceProfile; } if (!profileName.isEmpty()) { firstChoiceProfile = profileName; SimpleKeyGrabberButton *button = item->data(Qt::UserRole).value(); button->setValue(profileName, JoyButtonSlot::JoyLoadProfile); QMetaObject::invokeMethod(&helper, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(JoyButtonSlot *, button->getValue()), Q_ARG(int, index)); button->setToolTip(profileName); updateSlotsScrollArea(0); } } bool AdvanceButtonDialog::anySelectedNotKeybSlot() { for (auto item : ui->slotListWidget->selectedItems()) { auto slotMode = item->data(Qt::UserRole).value()->getValue()->getSlotMode(); if ((slotMode != JoyButtonSlot::JoySlotInputAction::JoyMix) && (slotMode != JoyButtonSlot::JoySlotInputAction::JoyKeyboard)) { return true; } } return false; } bool AdvanceButtonDialog::selectedNotMixSlot() { for (auto item : ui->slotListWidget->selectedItems()) { auto slotMode = item->data(Qt::UserRole).value()->getValue()->getSlotMode(); if (slotMode != JoyButtonSlot::JoySlotInputAction::JoyMix) { return true; } } return false; } void AdvanceButtonDialog::showFindExecutableWindow(bool) { QString preferredPath = QDir::homePath(); QString execWindFilepath = QFileDialog::getOpenFileName(this, tr("Choose Executable"), preferredPath); ui->execLineEdit->setText(execWindFilepath); } void AdvanceButtonDialog::changeSlotTypeDisplay(int index) { switch (index) { case 0: case 2: case 5: case 8: case 9: case 10: ui->slotControlsStackedWidget->setCurrentIndex(0); break; case 1: ui->slotControlsStackedWidget->setCurrentIndex(3); break; case 3: ui->slotControlsStackedWidget->setCurrentIndex(2); break; case 4: ui->slotControlsStackedWidget->setCurrentIndex(7); break; case 6: ui->slotControlsStackedWidget->setCurrentIndex(4); break; case 7: ui->slotControlsStackedWidget->setCurrentIndex(1); break; case 11: ui->slotControlsStackedWidget->setCurrentIndex(5); break; case 12: ui->slotControlsStackedWidget->setCurrentIndex(6); break; } } void AdvanceButtonDialog::changeSlotHelpText(int index) { switch (index) { case 0: ui->slotTypeHelpLabel->setText(tr("Insert a new blank slot.")); break; case 1: ui->slotTypeHelpLabel->setText(tr("Slots past a Cycle action will be executed " "on the next button press. Multiple cycles can be added " "in order to create partitions in a sequence.")); break; case 2: ui->slotTypeHelpLabel->setText(tr("Delays the time that the next slot is activated " "by the time specified. Slots activated before the " "delay will remain active after the delay time " "has passed.")); break; case 3: ui->slotTypeHelpLabel->setText(tr("Distance action specifies that the slots afterwards " "will only be executed when an axis is moved " "a certain range past the designated dead zone.")); break; case 4: ui->slotTypeHelpLabel->setText(tr("Execute program when slot is activated.")); break; case 5: ui->slotTypeHelpLabel->setText(tr("Insert a hold action. Slots after the action will only be " "executed if the button is held past the interval specified.")); break; case 6: ui->slotTypeHelpLabel->setText(tr("Chose a profile to load when this slot is activated.")); break; case 7: ui->slotTypeHelpLabel->setText(tr("Mouse mod action will modify all mouse speed settings " "by a specified percentage while the action is being processed. " "This can be useful for slowing down the mouse while " "sniping.")); break; case 8: ui->slotTypeHelpLabel->setText(tr("Insert a pause that occurs in between key presses.")); break; case 9: ui->slotTypeHelpLabel->setText(tr("Specify the time that keys past this slot should be " "held down.")); break; case 10: ui->slotTypeHelpLabel->setText(tr("Insert a release action. Slots after the action will only be " "executed after a button release if the button was held " "past the interval specified.")); break; case 11: ui->slotTypeHelpLabel->setText(tr("Change to selected set once slot is activated.")); break; case 12: ui->slotTypeHelpLabel->setText(tr("Full string will be typed when a " "slot is activated.")); break; } } int AdvanceButtonDialog::getOldRow() const { return oldRow; } JoyButton *AdvanceButtonDialog::getButton() const { return m_button; } AdvanceButtonDialogHelper const &AdvanceButtonDialog::getHelper() { return helper; } AdvanceButtonDialogHelper &AdvanceButtonDialog::getHelperLocal() { return helper; } AntiMicroX-antimicrox-b300273/src/gui/advancebuttondialog.h000066400000000000000000000125451471077622000237220ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ADVANCEBUTTONDIALOG_H #define ADVANCEBUTTONDIALOG_H #include "uihelpers/advancebuttondialoghelper.h" #include #include class JoyButton; class SimpleKeyGrabberButton; class QListWidgetItem; namespace Ui { class AdvanceButtonDialog; } class AdvanceButtonDialog : public QDialog { Q_OBJECT public: explicit AdvanceButtonDialog(JoyButton *button, QWidget *parent = 0); AdvanceButtonDialog(QWidget *parent = 0); ~AdvanceButtonDialog(); int getOldRow() const; JoyButton *getButton() const; AdvanceButtonDialogHelper const &getHelper(); protected: void connectButtonEvents(SimpleKeyGrabberButton *button); // AdvanceBtnDlgAssign class void appendBlankKeyGrabber(); // AdvanceBtnDlgAssign class int actionTimeConvert(); // AdvanceBtnDlgAssign class void changeTurboForSequences(); void fillTimeComboBoxes(); // AdvanceBtnDlgAssign class void refreshTimeComboBoxes(JoyButtonSlot *slot); // AdvanceBtnDlgAssign class void updateWindowTitleButtonName(); // AdvanceBtnDlgAssign class void populateAutoResetInterval(); // AdvanceBtnDlgAssign class void disconnectTimeBoxesEvents(); // AdvanceBtnDlgAssign class void connectTimeBoxesEvents(); // AdvanceBtnDlgAssign class void resetTimeBoxes(); // AdvanceBtnDlgAssign class void populateSetSelectionComboBox(); void populateSlotSetSelectionComboBox(); void findTurboModeComboIndex(); void showSelectProfileWind(QListWidgetItem *item, QString &firstChoiceProfile); bool anySelectedNotKeybSlot(); bool selectedNotMixSlot(); signals: void toggleChanged(bool state); void turboChanged(bool state); void slotsChanged(); // AdvanceBtnDlgAssign class void turboButtonEnabledChange(bool state); public slots: void placeNewSlot(JoyButtonSlot *slot); // AdvanceBtnDlgAssign class void clearAllSlots(); // AdvanceBtnDlgAssign class private slots: void changeTurboText(int value); void updateTurboIntervalValue(int value); void checkTurboSetting(bool state); void updateSlotsScrollArea(int value); // AdvanceBtnDlgAssign class void deleteSlot(bool showWarning = true); // AdvanceBtnDlgAssign class void insertSlot(); // AdvanceBtnDlgAssign class void joinSlot(); // AdvanceBtnDlgAssign class void splitSlot(); // AdvanceBtnDlgAssign class void insertCycleSlot(QListWidgetItem *item); // AdvanceBtnDlgAssign class void insertTextEntrySlot(QListWidgetItem *item); // AdvanceBtnDlgAssign class void insertExecuteSlot(QListWidgetItem *item, QStringList &prevExecAndArgs); // AdvanceBtnDlgAssign class void updateActionTimeLabel(); void updateSetSelection(); void checkTurboIntervalValue(int value); void performStatsWidgetRefresh(QListWidgetItem *item); void checkSlotTimeUpdate(); // AdvanceBtnDlgAssign class void checkSlotMouseModUpdate(); // AdvanceBtnDlgAssign class void checkSlotDistanceUpdate(); // AdvanceBtnDlgAssign class void checkSlotSetChangeUpdate(); // AdvanceBtnDlgAssign class void checkCycleResetWidgetStatus(bool enabled); // AdvanceBtnDlgAssign class void setButtonCycleResetInterval(double value); // AdvanceBtnDlgAssign class void setButtonCycleReset(bool enabled); // AdvanceBtnDlgAssign class void setButtonTurboMode(int value); void showSelectProfileWindow(); void showFindExecutableWindow(bool); // AdvanceBtnDlgAssign class void changeSlotTypeDisplay(int index); // AdvanceBtnDlgAssign class void changeSlotHelpText(int index); // AdvanceBtnDlgAssign class private: Ui::AdvanceButtonDialog *ui; AdvanceButtonDialogHelper &getHelperLocal(); enum SlotTypeComboIndex { KBMouseSlot = 0, CycleSlot, DelaySlot, DistanceSlot, ExecuteSlot, HoldSlot, LoadSlot, MouseModSlot, PauseSlot, PressTimeSlot, ReleaseSlot, SetChangeSlot, TextEntry }; int oldRow; JoyButton *m_button; AdvanceButtonDialogHelper helper; QReadWriteLock joinLock; void insertKindOfSlot(QListWidgetItem *item, int slotProperty, JoyButtonSlot::JoySlotInputAction inputAction); // AdvanceBtnDlgAssign class }; #endif // ADVANCEBUTTONDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/advancebuttondialog.ui000066400000000000000000001252751471077622000241150ustar00rootroot00000000000000 AdvanceButtonDialog Qt::NonModal 0 0 750 480 0 0 750 480 Advanced false 6 4 0 true 0 0 200 16777215 0 Assignments Toggle Turbo Set Selector 0 0 0 0 0 0 100 16777215 100 false QFrame::StyledPanel QFrame::Sunken 1 0 Qt::ScrollBarAlwaysOff QAbstractItemView::ExtendedSelection QListView::LeftToRight 0 QListView::ListMode false Qt::Vertical QSizePolicy::Fixed 20 10 0 Qt::Horizontal QSizePolicy::Fixed 50 20 Blank or KB/M Cycle Delay Distance Execute Hold Load Mouse Mod Pause Press Time Release Set Change Text Entry Qt::Horizontal QSizePolicy::Fixed 50 20 4 0 20 Insert a new blank slot. Insert .. 0 20 Delete a slot. Delete .. 0 20 Join :/images/actions/join_slots.png:/images/actions/join_slots.png 0 20 Split :/images/actions/split_slot.png:/images/actions/split_slot.png 0 20 Clear all currently assigned slots. Clear All .. Qt::Vertical QSizePolicy::Fixed 20 2 Placeholder true 0 Qt::Vertical QSizePolicy::Fixed 20 20 40 0 0 75 true Specify the duration of an inserted Pause or Hold slot. Time: 50 false 0.01s 10 0m 0 0 0 0 11 0 0 0 0 0 0 0 0s 75 true &Mouse Speed Mod: mouseSpeedModSpinBox 81 0 Set the percentage that mouse speeds will be modified by. % 1 400 1 100 20 75 true Specify the range past an axis dead zone in which a sequence of actions will execute. Distance: distanceSpinBox 81 0 Specify the range past an axis dead zone in which a sequence of actions will execute. % 1 100 1 10 true 75 true Auto Reset Cycle After false 60.000000000000000 0.500000000000000 1.000000000000000 true 75 true seconds Choose Profile Executable: ... Arguments: Qt::Vertical QSizePolicy::Expanding 20 10 20 Enabled Qt::Vertical 20 302 0 0 Enabled 0 0 Mode: false <html><head/><body><p>Normal: Repeatedly press and release a button by the chosen rate.</p><p>Gradient: Modify the button press and button release delay based on how far an axis has been moved. The rate will remain the same.</p><p>Pulse: Modify how many times a button is pressed and released per second. The button delay will remain the same.</p></body></html> Normal Gradient Pulse Qt::Vertical QSizePolicy::Fixed 20 20 6 0 0 0 0 0 16777215 20 Delay: 0 0 0 0 16777215 20 0.10s false 0 0 0 400 10 10 true Qt::Horizontal false false QSlider::TicksBelow 10 Qt::Vertical QSizePolicy::Fixed 20 20 Rate: 10.0/s 30 Enabled 0 30 Disabled Select Set 1 One Way Select Set 1 Two Way Select Set 1 While Held Select Set 2 One Way Select Set 2 Two Way Select Set 2 While Held Select Set 3 One Way Select Set 3 Two Way Select Set 3 While Held Select Set 4 One Way Select Set 4 Two Way Select Set 4 While Held Select Set 5 One Way Select Set 5 Two Way Select Set 5 While Held Select Set 6 One Way Select Set 6 Two Way Select Set 6 While Held Select Set 7 One Way Select Set 7 Two Way Select Set 7 While Held Select Set 8 One Way Select Set 8 Two Way Select Set 8 While Held Qt::Vertical 20 289 Qt::Horizontal Qt::Horizontal QDialogButtonBox::Close SlotItemListWidget QListWidget

slotitemlistwidget.h
buttonBox accepted() AdvanceButtonDialog accept() 222 406 157 274 buttonBox rejected() AdvanceButtonDialog reject() 290 412 286 274 listWidget currentRowChanged(int) stackedWidget setCurrentIndex(int) 119 90 573 14 AntiMicroX-antimicrox-b300273/src/gui/advancestickassignmentdialog.cpp000066400000000000000000001331651471077622000261520ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "advancestickassignmentdialog.h" #include "ui_advancestickassignmentdialog.h" #include "globalvariables.h" #include "joycontrolstick.h" #include "joystick.h" #include "vdpad.h" #include #include #include #include #include #include #include #include AdvanceStickAssignmentDialog::AdvanceStickAssignmentDialog(Joystick *joystick, QWidget *parent) : QDialog(parent, Qt::Window) , ui(new Ui::AdvanceStickAssignmentDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); this->joystick = joystick; joystick->getActiveSetJoystick()->setIgnoreEventState(true); joystick->getActiveSetJoystick()->release(); joystick->resetButtonDownCount(); QString tempHeaderLabel = ui->joystickNumberLabel->text(); tempHeaderLabel = tempHeaderLabel.arg(joystick->getSDLName()).arg(joystick->getRealJoyNumber()); ui->joystickNumberLabel->setText(tempHeaderLabel); ui->joystickNumberLabel2->setText(tempHeaderLabel); tempHeaderLabel = ui->hatNumberLabel->text(); tempHeaderLabel = tempHeaderLabel.arg(joystick->getNumberHats()); ui->hatNumberLabel->setText(tempHeaderLabel); ui->xAxisOneComboBox->addItem("", QVariant(0)); ui->yAxisOneComboBox->addItem("", QVariant(0)); ui->xAxisTwoComboBox->addItem("", QVariant(0)); ui->yAxisTwoComboBox->addItem("", QVariant(0)); for (int i = 0; i < joystick->getNumberAxes(); i++) { ui->xAxisOneComboBox->addItem(tr("Axis %1").arg(i + 1), QVariant(i)); ui->yAxisOneComboBox->addItem(tr("Axis %1").arg(i + 1), QVariant(i)); ui->xAxisTwoComboBox->addItem(tr("Axis %1").arg(i + 1), QVariant(i)); ui->yAxisTwoComboBox->addItem(tr("Axis %1").arg(i + 1), QVariant(i)); } JoyControlStick *stick1 = joystick->getActiveSetJoystick()->getJoyStick(0); JoyControlStick *stick2 = joystick->getActiveSetJoystick()->getJoyStick(1); refreshStickConfiguration(stick1, stick2); populateDPadComboBoxes(); refreshVDPadsConfiguration(); ui->versionTwoMessageLabel->setVisible(false); connect(ui->enableOneCheckBox, &QCheckBox::clicked, this, &AdvanceStickAssignmentDialog::changeStateStickOneWidgets); connect(ui->enableTwoCheckBox, &QCheckBox::clicked, this, &AdvanceStickAssignmentDialog::changeStateStickTwoWidgets); connect(ui->vdpadEnableCheckBox, &QCheckBox::clicked, this, &AdvanceStickAssignmentDialog::changeStateVDPadWidgets); connect(ui->xAxisOneComboBox, static_cast(&QComboBox::currentIndexChanged), [this]() { this->checkForAxisAssignmentStickOne(ui->xAxisOneComboBox); }); connect(ui->yAxisOneComboBox, static_cast(&QComboBox::currentIndexChanged), [this]() { this->checkForAxisAssignmentStickOne(ui->yAxisOneComboBox); }); connect(ui->xAxisTwoComboBox, static_cast(&QComboBox::currentIndexChanged), [this]() { this->checkForAxisAssignmentStickTwo(ui->xAxisTwoComboBox); }); connect(ui->yAxisTwoComboBox, static_cast(&QComboBox::currentIndexChanged), [this]() { this->checkForAxisAssignmentStickTwo(ui->yAxisTwoComboBox); }); connect(ui->quickAssignStick1PushButton, &QPushButton::clicked, this, &AdvanceStickAssignmentDialog::openQuickAssignDialogStick1); connect(ui->quickAssignStick2PushButton, &QPushButton::clicked, this, &AdvanceStickAssignmentDialog::openQuickAssignDialogStick2); enableVDPadComboBoxes(); connect(this, &AdvanceStickAssignmentDialog::stickConfigurationChanged, this, &AdvanceStickAssignmentDialog::disableVDPadComboBoxes); connect(this, &AdvanceStickAssignmentDialog::stickConfigurationChanged, this, &AdvanceStickAssignmentDialog::populateDPadComboBoxes); connect(this, &AdvanceStickAssignmentDialog::stickConfigurationChanged, this, &AdvanceStickAssignmentDialog::refreshVDPadsConfiguration); connect(this, &AdvanceStickAssignmentDialog::stickConfigurationChanged, this, &AdvanceStickAssignmentDialog::enableVDPadComboBoxes); connect(ui->vdpadUpPushButton, &QPushButton::clicked, this, &AdvanceStickAssignmentDialog::openAssignVDPadUp); connect(ui->vdpadDownPushButton, &QPushButton::clicked, this, &AdvanceStickAssignmentDialog::openAssignVDPadDown); connect(ui->vdpadLeftPushButton, &QPushButton::clicked, this, &AdvanceStickAssignmentDialog::openAssignVDPadLeft); connect(ui->vdpadRightPushButton, &QPushButton::clicked, this, &AdvanceStickAssignmentDialog::openAssignVDPadRight); connect(this, &AdvanceStickAssignmentDialog::finished, this, &AdvanceStickAssignmentDialog::reenableButtonEvents); } // for tests AdvanceStickAssignmentDialog::AdvanceStickAssignmentDialog(QWidget *parent) : QDialog(parent, Qt::Window) , ui(new Ui::AdvanceStickAssignmentDialog) { } AdvanceStickAssignmentDialog::~AdvanceStickAssignmentDialog() { delete ui; } void AdvanceStickAssignmentDialog::checkForAxisAssignmentStickOne(QWidget *comboBox) { checkForAxisAssignmentSticks(comboBox, ui->xAxisTwoComboBox, ui->yAxisTwoComboBox, 0); } void AdvanceStickAssignmentDialog::checkForAxisAssignmentStickTwo(QWidget *comboBox) { checkForAxisAssignmentSticks(comboBox, ui->xAxisTwoComboBox, ui->yAxisTwoComboBox, 1); } void AdvanceStickAssignmentDialog::checkForAxisAssignmentSticks(QWidget *comboBox, QComboBox *xAxisComboBox, QComboBox *yAxisComboBox, int controlStickNumber) { if ((xAxisComboBox->currentIndex() > 0) && (yAxisComboBox->currentIndex() > 0)) { if (xAxisComboBox->currentIndex() != yAxisComboBox->currentIndex()) { int originset = 0; for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); JoyAxis *axis1 = currentset->getJoyAxis(xAxisComboBox->currentIndex() - 1); JoyAxis *axis2 = currentset->getJoyAxis(yAxisComboBox->currentIndex() - 1); if ((axis1 != nullptr) && (axis2 != nullptr) && (currentset->getJoyStick(controlStickNumber) != nullptr)) { currentset->getJoyStick(controlStickNumber)->replaceAxes(axis1, axis2); } else if ((axis1 != nullptr) && (axis2 != nullptr) && (currentset->getJoyStick(controlStickNumber) == nullptr)) { JoyControlStick *controlstick = new JoyControlStick(axis1, axis2, controlStickNumber, originset, currentset); currentset->addControlStick(controlStickNumber, controlstick); } originset++; } JoyControlStick *stick1 = joystick->getActiveSetJoystick()->getJoyStick(0); JoyControlStick *stick2 = joystick->getActiveSetJoystick()->getJoyStick(1); refreshStickConfiguration(stick1, stick2); emit stickConfigurationChanged(); } else if (comboBox == xAxisComboBox) { yAxisComboBox->setCurrentIndex(0); } else if (comboBox == yAxisComboBox) { xAxisComboBox->setCurrentIndex(0); } } } void AdvanceStickAssignmentDialog::changeStateVDPadWidgets(bool enabledVDPads) { ui->vdpadUpComboBox->setEnabled(enabledVDPads); ui->vdpadDownComboBox->setEnabled(enabledVDPads); ui->vdpadLeftComboBox->setEnabled(enabledVDPads); ui->vdpadRightComboBox->setEnabled(enabledVDPads); ui->vdpadUpPushButton->setEnabled(enabledVDPads); ui->vdpadDownPushButton->setEnabled(enabledVDPads); ui->vdpadLeftPushButton->setEnabled(enabledVDPads); ui->vdpadRightPushButton->setEnabled(enabledVDPads); int originset = 0; for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); if (!currentset->getVDPad(0) && enabledVDPads) { currentset->addVDPad(0, new VDPad(0, originset, currentset, currentset)); } else { currentset->removeVDPad(0); } originset++; } } void AdvanceStickAssignmentDialog::changeStateStickOneWidgets(bool enabled) { if (enabled) { ui->xAxisOneComboBox->setEnabled(true); ui->yAxisOneComboBox->setEnabled(true); ui->enableTwoCheckBox->setEnabled(true); ui->quickAssignStick1PushButton->setEnabled(true); } else { ui->xAxisOneComboBox->setEnabled(false); ui->xAxisOneComboBox->setCurrentIndex(0); ui->yAxisOneComboBox->setEnabled(false); ui->yAxisOneComboBox->setCurrentIndex(0); ui->xAxisTwoComboBox->setEnabled(false); ui->yAxisTwoComboBox->setEnabled(false); ui->xAxisTwoComboBox->setCurrentIndex(0); ui->yAxisTwoComboBox->setCurrentIndex(0); ui->enableTwoCheckBox->setEnabled(false); ui->enableTwoCheckBox->setChecked(false); ui->quickAssignStick1PushButton->setEnabled(false); if (joystick->getActiveSetJoystick()->getJoyStick(1) != nullptr) joystick->removeControlStick(1); if (joystick->getActiveSetJoystick()->getJoyStick(0) != nullptr) joystick->removeControlStick(0); } } void AdvanceStickAssignmentDialog::changeStateStickTwoWidgets(bool enabled) { if (enabled) { ui->xAxisTwoComboBox->setEnabled(true); ui->yAxisTwoComboBox->setEnabled(true); ui->quickAssignStick2PushButton->setEnabled(true); } else { ui->xAxisTwoComboBox->setEnabled(false); ui->xAxisTwoComboBox->setCurrentIndex(0); ui->yAxisTwoComboBox->setEnabled(false); ui->yAxisTwoComboBox->setCurrentIndex(0); ui->quickAssignStick2PushButton->setEnabled(false); if (joystick->getActiveSetJoystick()->getJoyStick(1) != nullptr) { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { set.value()->removeControlStick(1); } } } } void AdvanceStickAssignmentDialog::refreshStickConfiguration(JoyControlStick *stick1, JoyControlStick *stick2) { if ((stick1 != nullptr) && (stick1->getAxisX() != nullptr) && (stick1->getAxisY() != nullptr)) { refreshSticksForAxes(true, stick1->getAxisX()->getRealJoyIndex(), stick1->getAxisY()->getRealJoyIndex(), ui->xAxisOneComboBox, ui->yAxisOneComboBox, ui->enableOneCheckBox, ui->quickAssignStick1PushButton); } else { refreshSticksForAxes(false, 0, 0, ui->xAxisOneComboBox, ui->yAxisOneComboBox, ui->enableOneCheckBox, ui->quickAssignStick1PushButton); } if ((stick2 != nullptr) && (stick2->getAxisX() != nullptr) && (stick2->getAxisY() != nullptr)) { refreshSticksForAxes(true, stick2->getAxisX()->getRealJoyIndex(), stick2->getAxisY()->getRealJoyIndex(), ui->xAxisTwoComboBox, ui->yAxisTwoComboBox, ui->enableTwoCheckBox, ui->quickAssignStick2PushButton); } else { refreshSticksForAxes(false, 0, 0, ui->xAxisTwoComboBox, ui->yAxisTwoComboBox, ui->enableTwoCheckBox, ui->quickAssignStick2PushButton); } } void AdvanceStickAssignmentDialog::refreshSticksForAxes(bool axesExist, int xAxisComboBoxIndex, int yAxisComboBoxIndex, QComboBox *xAxisComboBox, QComboBox *yAxisComboBox, QCheckBox *enabledSticksCheckbox, QPushButton *quickAssignBtn) { xAxisComboBox->setCurrentIndex(xAxisComboBoxIndex); yAxisComboBox->setCurrentIndex(yAxisComboBoxIndex); xAxisComboBox->setEnabled(axesExist); yAxisComboBox->setEnabled(axesExist); enabledSticksCheckbox->setEnabled(axesExist); enabledSticksCheckbox->setChecked(axesExist); quickAssignBtn->setEnabled(axesExist); } void AdvanceStickAssignmentDialog::refreshVDPadsConfiguration() { VDPad *vdpad = joystick->getActiveSetJoystick()->getVDPad(0); if (vdpad != nullptr) { ui->vdpadEnableCheckBox->setChecked(true); ui->vdpadUpComboBox->setEnabled(true); ui->vdpadDownComboBox->setEnabled(true); ui->vdpadLeftComboBox->setEnabled(true); ui->vdpadRightComboBox->setEnabled(true); ui->vdpadUpPushButton->setEnabled(true); ui->vdpadDownPushButton->setEnabled(true); ui->vdpadLeftPushButton->setEnabled(true); ui->vdpadRightPushButton->setEnabled(true); JoyButton *upButton = vdpad->getVButton(JoyDPadButton::DpadUp); refreshVDPadConf(upButton, ui->vdpadUpComboBox); JoyButton *downButton = vdpad->getVButton(JoyDPadButton::DpadDown); refreshVDPadConf(downButton, ui->vdpadDownComboBox); JoyButton *leftButton = vdpad->getVButton(JoyDPadButton::DpadLeft); refreshVDPadConf(leftButton, ui->vdpadLeftComboBox); JoyButton *rightButton = vdpad->getVButton(JoyDPadButton::DpadRight); refreshVDPadConf(rightButton, ui->vdpadRightComboBox); } else { ui->vdpadEnableCheckBox->setChecked(false); ui->vdpadUpComboBox->setCurrentIndex(0); ui->vdpadUpComboBox->setEnabled(false); ui->vdpadDownComboBox->setCurrentIndex(0); ui->vdpadDownComboBox->setEnabled(false); ui->vdpadLeftComboBox->setCurrentIndex(0); ui->vdpadLeftComboBox->setEnabled(false); ui->vdpadRightComboBox->setCurrentIndex(0); ui->vdpadRightComboBox->setEnabled(false); ui->vdpadUpPushButton->setEnabled(false); ui->vdpadDownPushButton->setEnabled(false); ui->vdpadLeftPushButton->setEnabled(false); ui->vdpadRightPushButton->setEnabled(false); } } void AdvanceStickAssignmentDialog::refreshVDPadConf(JoyButton *vdpadButton, QComboBox *vpadComboBox) { if (vdpadButton != nullptr) { int buttonindex = 0; if (typeid(*vdpadButton) == typeid(JoyAxisButton)) { JoyAxisButton *axisbutton = qobject_cast(vdpadButton); JoyAxis *axis = axisbutton->getAxis(); QList templist; templist.append(QVariant(axis->getRealJoyIndex())); templist.append(QVariant(axisbutton->getJoyNumber())); buttonindex = vpadComboBox->findData(templist); } else { QList templist; templist.append(QVariant(0)); templist.append(QVariant(vdpadButton->getRealJoyNumber())); buttonindex = vpadComboBox->findData(templist); } if (buttonindex == -1) vdpadButton->getVDPad()->removeVButton(vdpadButton); else vpadComboBox->setCurrentIndex(buttonindex); } } void AdvanceStickAssignmentDialog::populateDPadComboBoxes() { ui->vdpadUpComboBox->clear(); ui->vdpadDownComboBox->clear(); ui->vdpadLeftComboBox->clear(); ui->vdpadRightComboBox->clear(); ui->vdpadUpComboBox->addItem("", QVariant(0)); ui->vdpadDownComboBox->addItem("", QVariant(0)); ui->vdpadLeftComboBox->addItem("", QVariant(0)); ui->vdpadRightComboBox->addItem("", QVariant(0)); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if (!axis->isPartControlStick()) { QList templist; templist.append(QVariant(i + 1)); templist.append(QVariant(0)); ui->vdpadUpComboBox->addItem(tr("Axis %1 -").arg(QString::number(i + 1)), templist); ui->vdpadDownComboBox->addItem(tr("Axis %1 -").arg(QString::number(i + 1)), templist); ui->vdpadLeftComboBox->addItem(tr("Axis %1 -").arg(QString::number(i + 1)), templist); ui->vdpadRightComboBox->addItem(tr("Axis %1 -").arg(QString::number(i + 1)), templist); templist.clear(); templist.append(QVariant(i + 1)); templist.append(QVariant(1)); ui->vdpadUpComboBox->addItem(tr("Axis %1 +").arg(QString::number(i + 1)), templist); ui->vdpadDownComboBox->addItem(tr("Axis %1 +").arg(QString::number(i + 1)), templist); ui->vdpadLeftComboBox->addItem(tr("Axis %1 +").arg(QString::number(i + 1)), templist); ui->vdpadRightComboBox->addItem(tr("Axis %1 +").arg(QString::number(i + 1)), templist); } } for (int i = 0; i < joystick->getNumberButtons(); i++) { QList templist; templist.append(QVariant(0)); templist.append(QVariant(i + 1)); ui->vdpadUpComboBox->addItem(tr("Button %1").arg(QString::number(i + 1)), templist); ui->vdpadDownComboBox->addItem(tr("Button %1").arg(QString::number(i + 1)), templist); ui->vdpadLeftComboBox->addItem(tr("Button %1").arg(QString::number(i + 1)), templist); ui->vdpadRightComboBox->addItem(tr("Button %1").arg(QString::number(i + 1)), templist); } } void AdvanceStickAssignmentDialog::changeVDPadUpButton(int index) { if (index > 0) { if (ui->vdpadDownComboBox->currentIndex() == index) { ui->vdpadDownComboBox->setCurrentIndex(0); } else if (ui->vdpadLeftComboBox->currentIndex() == index) { ui->vdpadLeftComboBox->setCurrentIndex(0); } else if (ui->vdpadRightComboBox->currentIndex() == index) { ui->vdpadRightComboBox->setCurrentIndex(0); } QVariant temp = ui->vdpadUpComboBox->itemData(index); QList templist = temp.toList(); if (templist.size() == 2) { int axis = templist.at(0).toInt(); int button = templist.at(1).toInt(); if ((axis > 0) && (button >= 0)) { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); JoyAxis *currentaxis = currentset->getJoyAxis(axis - 1); JoyButton *currentbutton = nullptr; if (button == 0) { currentbutton = currentaxis->getNAxisButton(); } else if (button == 1) { currentbutton = currentaxis->getPAxisButton(); } vdpad->addVButton(JoyDPadButton::DpadUp, currentbutton); } } else if (button > 0) { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); JoyButton *currentbutton = currentset->getJoyButton(button - 1); if (currentbutton != nullptr) { vdpad->addVButton(JoyDPadButton::DpadUp, currentbutton); } } } } } else { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); if ((vdpad != nullptr) && vdpad->getVButton(JoyDPadButton::DpadUp)) { vdpad->removeVButton(JoyDPadButton::DpadUp); } } } } void AdvanceStickAssignmentDialog::changeVDPadDownButton(int index) { if (index > 0) { if (ui->vdpadUpComboBox->currentIndex() == index) { ui->vdpadUpComboBox->setCurrentIndex(0); } else if (ui->vdpadLeftComboBox->currentIndex() == index) { ui->vdpadLeftComboBox->setCurrentIndex(0); } else if (ui->vdpadRightComboBox->currentIndex() == index) { ui->vdpadRightComboBox->setCurrentIndex(0); } QVariant temp = ui->vdpadDownComboBox->itemData(index); QList templist = temp.toList(); if (templist.size() == 2) { int axis = templist.at(0).toInt(); int button = templist.at(1).toInt(); if ((axis > 0) && (button >= 0)) { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); JoyAxis *currentaxis = currentset->getJoyAxis(axis - 1); JoyButton *currentbutton = nullptr; if (button == 0) { currentbutton = currentaxis->getNAxisButton(); } else if (button == 1) { currentbutton = currentaxis->getPAxisButton(); } vdpad->addVButton(JoyDPadButton::DpadDown, currentbutton); } } else if (button > 0) { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); JoyButton *currentbutton = currentset->getJoyButton(button - 1); if (currentbutton != nullptr) { vdpad->addVButton(JoyDPadButton::DpadDown, currentbutton); } } } } } else { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); if ((vdpad != nullptr) && vdpad->getVButton(JoyDPadButton::DpadDown)) { vdpad->removeVButton(JoyDPadButton::DpadDown); } } } } void AdvanceStickAssignmentDialog::changeVDPadLeftButton(int index) { if (index > 0) { if (ui->vdpadUpComboBox->currentIndex() == index) { ui->vdpadUpComboBox->setCurrentIndex(0); } else if (ui->vdpadDownComboBox->currentIndex() == index) { ui->vdpadDownComboBox->setCurrentIndex(0); } else if (ui->vdpadRightComboBox->currentIndex() == index) { ui->vdpadRightComboBox->setCurrentIndex(0); } QVariant temp = ui->vdpadLeftComboBox->itemData(index); QList templist = temp.toList(); if (templist.size() == 2) { int axis = templist.at(0).toInt(); int button = templist.at(1).toInt(); if ((axis > 0) && (button >= 0)) { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); JoyAxis *currentaxis = currentset->getJoyAxis(axis - 1); JoyButton *currentbutton = nullptr; if (button == 0) { currentbutton = currentaxis->getNAxisButton(); } else if (button == 1) { currentbutton = currentaxis->getPAxisButton(); } vdpad->addVButton(JoyDPadButton::DpadLeft, currentbutton); } } else if (button > 0) { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); JoyButton *currentbutton = currentset->getJoyButton(button - 1); if (currentbutton != nullptr) { vdpad->addVButton(JoyDPadButton::DpadLeft, currentbutton); } } } } } else { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); if ((vdpad != nullptr) && vdpad->getVButton(JoyDPadButton::DpadLeft)) { vdpad->removeVButton(JoyDPadButton::DpadLeft); } } } } void AdvanceStickAssignmentDialog::changeVDPadRightButton(int index) { if (index > 0) { if (ui->vdpadUpComboBox->currentIndex() == index) { ui->vdpadUpComboBox->setCurrentIndex(0); } else if (ui->vdpadDownComboBox->currentIndex() == index) { ui->vdpadDownComboBox->setCurrentIndex(0); } else if (ui->vdpadLeftComboBox->currentIndex() == index) { ui->vdpadLeftComboBox->setCurrentIndex(0); } QVariant temp = ui->vdpadRightComboBox->itemData(index); QList templist = temp.toList(); if (templist.size() == 2) { int axis = templist.at(0).toInt(); int button = templist.at(1).toInt(); if ((axis > 0) && (button >= 0)) { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); JoyAxis *currentaxis = currentset->getJoyAxis(axis - 1); JoyButton *currentbutton = nullptr; if (button == 0) { currentbutton = currentaxis->getNAxisButton(); } else if (button == 1) { currentbutton = currentaxis->getPAxisButton(); } vdpad->addVButton(JoyDPadButton::DpadRight, currentbutton); } } else if (button > 0) { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); JoyButton *currentbutton = currentset->getJoyButton(button - 1); if (currentbutton != nullptr) { vdpad->addVButton(JoyDPadButton::DpadRight, currentbutton); } } } } } else { for (auto set = joystick->getJoystick_sets().begin(); set != joystick->getJoystick_sets().end(); ++set) { SetJoystick *currentset = set.value(); VDPad *vdpad = currentset->getVDPad(0); if ((vdpad != nullptr) && vdpad->getVButton(JoyDPadButton::DpadRight)) { vdpad->removeVButton(JoyDPadButton::DpadRight); } } } } void AdvanceStickAssignmentDialog::enableVDPadComboBoxes() { connect(ui->vdpadUpComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceStickAssignmentDialog::changeVDPadUpButton); connect(ui->vdpadDownComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceStickAssignmentDialog::changeVDPadDownButton); connect(ui->vdpadLeftComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceStickAssignmentDialog::changeVDPadLeftButton); connect(ui->vdpadRightComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceStickAssignmentDialog::changeVDPadRightButton); } void AdvanceStickAssignmentDialog::disableVDPadComboBoxes() { disconnect(ui->vdpadUpComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceStickAssignmentDialog::changeVDPadUpButton); disconnect(ui->vdpadDownComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceStickAssignmentDialog::changeVDPadDownButton); disconnect(ui->vdpadLeftComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceStickAssignmentDialog::changeVDPadLeftButton); disconnect(ui->vdpadRightComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AdvanceStickAssignmentDialog::changeVDPadRightButton); } void AdvanceStickAssignmentDialog::openQuickAssignDialogStick1() { QMessageBox msgBox; msgBox.setText(tr("Move stick 1 along the X axis")); msgBox.setStandardButtons(QMessageBox::Close); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if (axis != nullptr) { connect(axis, &JoyAxis::active, &msgBox, &QMessageBox::close); connect(axis, &JoyAxis::active, this, [this, axis] { ui->xAxisOneComboBox->setCurrentIndex(axis->getRealJoyIndex()); }); } } msgBox.exec(); msgBox.setText(tr("Move stick 1 along the Y axis")); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if (axis != nullptr) { disconnect(axis, &JoyAxis::active, &msgBox, &QMessageBox::close); disconnect(axis, &JoyAxis::active, this, nullptr); connect(axis, &JoyAxis::active, &msgBox, &QMessageBox::close); connect(axis, &JoyAxis::active, this, [this, axis] { ui->yAxisOneComboBox->setCurrentIndex(axis->getRealJoyIndex()); }); } } msgBox.exec(); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if (axis != nullptr) { disconnect(axis, &JoyAxis::active, &msgBox, &QMessageBox::close); disconnect(axis, &JoyAxis::active, this, nullptr); } } } void AdvanceStickAssignmentDialog::openQuickAssignDialogStick2() { QMessageBox msgBox; msgBox.setText(tr("Move stick 2 along the X axis")); msgBox.setStandardButtons(QMessageBox::Close); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if (axis != nullptr) { connect(axis, &JoyAxis::active, &msgBox, &QMessageBox::close); connect(axis, &JoyAxis::active, this, [this, axis] { ui->xAxisTwoComboBox->setCurrentIndex(axis->getRealJoyIndex()); }); } } msgBox.exec(); msgBox.setText(tr("Move stick 2 along the Y axis")); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if (axis != nullptr) { disconnect(axis, &JoyAxis::active, &msgBox, &QMessageBox::close); disconnect(axis, &JoyAxis::active, this, nullptr); connect(axis, &JoyAxis::active, &msgBox, &QMessageBox::close); connect(axis, &JoyAxis::active, this, [this, axis] { ui->yAxisTwoComboBox->setCurrentIndex(axis->getRealJoyIndex()); }); } } msgBox.exec(); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if (axis != nullptr) { disconnect(axis, &JoyAxis::active, &msgBox, &QMessageBox::close); disconnect(axis, &JoyAxis::active, this, nullptr); } } } void AdvanceStickAssignmentDialog::reenableButtonEvents() { joystick->getActiveSetJoystick()->setIgnoreEventState(false); joystick->getActiveSetJoystick()->release(); } void AdvanceStickAssignmentDialog::openAssignVDPadUp() { QMessageBox msgBox; msgBox.setText(tr("Press a button or move an axis")); msgBox.setStandardButtons(QMessageBox::Close); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if ((axis != nullptr) && !axis->isPartControlStick()) { JoyAxisButton *axbtn = axis->getNAxisButton(); connect(axis->getNAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); connect(axis->getNAxisButton(), &JoyAxisButton::clicked, this, [this, axbtn] { quickAssignVDPadUp(axbtn); }); JoyAxisButton *axbtnp = axis->getPAxisButton(); connect(axis->getPAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); connect(axis->getPAxisButton(), &JoyAxisButton::clicked, this, [this, axbtnp] { quickAssignVDPadUp(axbtnp); }); } } for (int i = 0; i < joystick->getNumberButtons(); i++) { JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); if (button != nullptr) { connect(button, &JoyButton::clicked, &msgBox, &QMessageBox::close); connect(button, &JoyButton::clicked, this, [this, button]() { quickAssignVDPadUpBtn(button); }); } } msgBox.exec(); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if ((axis != nullptr) && !axis->isPartControlStick()) { disconnect(axis->getNAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); disconnect(axis->getNAxisButton(), &JoyAxisButton::clicked, this, nullptr); disconnect(axis->getPAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); disconnect(axis->getPAxisButton(), &JoyAxisButton::clicked, this, nullptr); } } for (int i = 0; i < joystick->getNumberButtons(); i++) { JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); if (button != nullptr) { disconnect(button, &JoyButton::clicked, &msgBox, &QMessageBox::close); disconnect(button, &JoyButton::clicked, this, nullptr); } } } void AdvanceStickAssignmentDialog::openAssignVDPadDown() { QMessageBox msgBox; msgBox.setText(tr("Press a button or move an axis")); msgBox.setStandardButtons(QMessageBox::Close); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if ((axis != nullptr) && !axis->isPartControlStick()) { JoyAxisButton *axbtn = axis->getNAxisButton(); connect(axis->getNAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); connect(axis->getNAxisButton(), &JoyAxisButton::clicked, this, [this, axbtn] { quickAssignVDPadDown(axbtn); }); JoyAxisButton *axbtnP = axis->getPAxisButton(); connect(axis->getPAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); connect(axis->getPAxisButton(), &JoyAxisButton::clicked, this, [this, axbtnP] { quickAssignVDPadDown(axbtnP); }); } } for (int i = 0; i < joystick->getNumberButtons(); i++) { JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); if (button != nullptr) { connect(button, &JoyButton::clicked, &msgBox, &QMessageBox::close); connect(button, &JoyButton::clicked, this, [this, button] { quickAssignVDPadDownJbtn(button); }); } } msgBox.exec(); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if ((axis != nullptr) && !axis->isPartControlStick()) { disconnect(axis->getNAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); disconnect(axis->getNAxisButton(), &JoyAxisButton::clicked, this, nullptr); disconnect(axis->getPAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); disconnect(axis->getPAxisButton(), &JoyAxisButton::clicked, this, nullptr); } } for (int i = 0; i < joystick->getNumberButtons(); i++) { JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); if (button != nullptr) { disconnect(button, &JoyButton::clicked, &msgBox, &QMessageBox::close); disconnect(button, &JoyButton::clicked, this, nullptr); } } } void AdvanceStickAssignmentDialog::openAssignVDPadLeft() { QMessageBox msgBox; msgBox.setText(tr("Press a button or move an axis")); msgBox.setStandardButtons(QMessageBox::Close); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if ((axis != nullptr) && !axis->isPartControlStick()) { JoyAxisButton *joyaxisN = axis->getNAxisButton(); connect(axis->getNAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); connect(axis->getNAxisButton(), &JoyAxisButton::clicked, this, [this, joyaxisN]() { quickAssignVDPadLeft(joyaxisN); }); JoyAxisButton *joyaxisP = axis->getPAxisButton(); connect(axis->getPAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); connect(axis->getPAxisButton(), &JoyAxisButton::clicked, this, [this, joyaxisP]() { quickAssignVDPadLeft(joyaxisP); }); } } for (int i = 0; i < joystick->getNumberButtons(); i++) { JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); if (button != nullptr) { connect(button, &JoyButton::clicked, &msgBox, &QMessageBox::close); connect(button, &JoyButton::clicked, this, [this, button] { quickAssignVDPadLeftJbtn(button); }); } } msgBox.exec(); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if ((axis != nullptr) && !axis->isPartControlStick()) { disconnect(axis->getNAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); disconnect(axis->getNAxisButton(), &JoyAxisButton::clicked, this, nullptr); disconnect(axis->getPAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); disconnect(axis->getPAxisButton(), &JoyAxisButton::clicked, this, nullptr); } } for (int i = 0; i < joystick->getNumberButtons(); i++) { JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); if (button != nullptr) { disconnect(button, &JoyButton::clicked, &msgBox, &QMessageBox::close); disconnect(button, &JoyButton::clicked, this, nullptr); } } } void AdvanceStickAssignmentDialog::openAssignVDPadRight() { QMessageBox msgBox; msgBox.setText(tr("Press a button or move an axis")); msgBox.setStandardButtons(QMessageBox::Close); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if ((axis != nullptr) && !axis->isPartControlStick()) { JoyAxisButton *joyaxisbtnN = axis->getNAxisButton(); connect(axis->getNAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); connect(axis->getNAxisButton(), &JoyAxisButton::clicked, this, [this, joyaxisbtnN] { quickAssignVDPadRight(joyaxisbtnN); }); JoyAxisButton *joyaxisbtnP = axis->getPAxisButton(); connect(axis->getPAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); connect(axis->getPAxisButton(), &JoyAxisButton::clicked, this, [this, joyaxisbtnP] { quickAssignVDPadRight(joyaxisbtnP); }); } } for (int i = 0; i < joystick->getNumberButtons(); i++) { JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); if (button != nullptr) { connect(button, &JoyButton::clicked, &msgBox, &QMessageBox::close); connect(button, &JoyButton::clicked, this, [this, button] { quickAssignVDPadRightJbtn(button); }); } } msgBox.exec(); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if ((axis != nullptr) && !axis->isPartControlStick()) { disconnect(axis->getNAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); disconnect(axis->getNAxisButton(), &JoyAxisButton::clicked, this, nullptr); disconnect(axis->getPAxisButton(), &JoyAxisButton::clicked, &msgBox, &QMessageBox::close); disconnect(axis->getPAxisButton(), &JoyAxisButton::clicked, this, nullptr); } } for (int i = 0; i < joystick->getNumberButtons(); i++) { JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); if (button != nullptr) { disconnect(button, &JoyButton::clicked, &msgBox, &QMessageBox::close); disconnect(button, &JoyButton::clicked, this, nullptr); } } } void AdvanceStickAssignmentDialog::quickAssignVDPadUp(JoyAxisButton *joyaxisbtn) { QList templist; templist.append(QVariant(joyaxisbtn->getAxis()->getRealJoyIndex())); if (joyaxisbtn->getAxis()->getNAxisButton() == joyaxisbtn) templist.append(QVariant(0)); else templist.append(QVariant(1)); int index = ui->vdpadUpComboBox->findData(templist); if (index > 0) { ui->vdpadUpComboBox->setCurrentIndex(index); } } void AdvanceStickAssignmentDialog::quickAssignVDPadUpBtn(JoyButton *joybtn) { QList templist; templist.append(QVariant(0)); templist.append(QVariant(joybtn->getJoyNumber() + 1)); int index = ui->vdpadUpComboBox->findData(templist); if (index > 0) { ui->vdpadUpComboBox->setCurrentIndex(index); } } void AdvanceStickAssignmentDialog::quickAssignVDPadDown(JoyAxisButton *axbtn) { QList templist; templist.append(QVariant(axbtn->getAxis()->getRealJoyIndex())); if (axbtn->getAxis()->getNAxisButton() == axbtn) templist.append(QVariant(0)); else templist.append(QVariant(1)); int index = ui->vdpadDownComboBox->findData(templist); if (index > 0) ui->vdpadDownComboBox->setCurrentIndex(index); } void AdvanceStickAssignmentDialog::quickAssignVDPadDownJbtn(JoyButton *joybtn) { QList templist; templist.append(QVariant(0)); templist.append(QVariant(joybtn->getJoyNumber() + 1)); int index = ui->vdpadDownComboBox->findData(templist); if (index > 0) ui->vdpadDownComboBox->setCurrentIndex(index); } void AdvanceStickAssignmentDialog::quickAssignVDPadLeft(JoyAxisButton *joyaxisbtn) { QList templist; templist.append(QVariant(joyaxisbtn->getAxis()->getRealJoyIndex())); if (joyaxisbtn->getAxis()->getNAxisButton() == joyaxisbtn) templist.append(QVariant(0)); else templist.append(QVariant(1)); int index = ui->vdpadLeftComboBox->findData(templist); if (index > 0) ui->vdpadLeftComboBox->setCurrentIndex(index); } void AdvanceStickAssignmentDialog::quickAssignVDPadLeftJbtn(JoyButton *joybtn) { QList templist; templist.append(QVariant(0)); templist.append(QVariant(joybtn->getJoyNumber() + 1)); int index = ui->vdpadLeftComboBox->findData(templist); if (index > 0) ui->vdpadLeftComboBox->setCurrentIndex(index); } void AdvanceStickAssignmentDialog::quickAssignVDPadRight(JoyAxisButton *joyaxisbtn) { QList templist; templist.append(QVariant(joyaxisbtn->getAxis()->getRealJoyIndex())); if (joyaxisbtn->getAxis()->getNAxisButton() == joyaxisbtn) templist.append(QVariant(0)); else templist.append(QVariant(1)); int index = ui->vdpadRightComboBox->findData(templist); if (index > 0) ui->vdpadRightComboBox->setCurrentIndex(index); } void AdvanceStickAssignmentDialog::quickAssignVDPadRightJbtn(JoyButton *joybtn) { QList templist; templist.append(QVariant(0)); templist.append(QVariant(joybtn->getJoyNumber() + 1)); int index = ui->vdpadRightComboBox->findData(templist); if (index > 0) ui->vdpadRightComboBox->setCurrentIndex(index); } Joystick *AdvanceStickAssignmentDialog::getJoystick() const { return joystick; } AntiMicroX-antimicrox-b300273/src/gui/advancestickassignmentdialog.h000066400000000000000000000066161471077622000256170ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ADVANCESTICKASSIGNMENTDIALOG_H #define ADVANCESTICKASSIGNMENTDIALOG_H #include class Joystick; class JoyAxisButton; class JoyButton; class QComboBox; class QCheckBox; class JoyControlStick; namespace Ui { class AdvanceStickAssignmentDialog; } class AdvanceStickAssignmentDialog : public QDialog { Q_OBJECT public: explicit AdvanceStickAssignmentDialog(Joystick *joystick, QWidget *parent = nullptr); AdvanceStickAssignmentDialog(QWidget *parent = nullptr); ~AdvanceStickAssignmentDialog(); Joystick *getJoystick() const; signals: void stickConfigurationChanged(); void vdpadConfigurationChanged(); private slots: void refreshStickConfiguration(JoyControlStick *stick1, JoyControlStick *stick2); void refreshVDPadsConfiguration(); void checkForAxisAssignmentStickOne(QWidget *comboBox); void checkForAxisAssignmentStickTwo(QWidget *comboBox); void changeStateStickOneWidgets(bool enabled); void changeStateStickTwoWidgets(bool enabled); void changeStateVDPadWidgets(bool enabledVDPads); void populateDPadComboBoxes(); void changeVDPadUpButton(int index); void changeVDPadDownButton(int index); void changeVDPadLeftButton(int index); void changeVDPadRightButton(int index); void disableVDPadComboBoxes(); void enableVDPadComboBoxes(); void openQuickAssignDialogStick1(); void openQuickAssignDialogStick2(); void openAssignVDPadUp(); void openAssignVDPadDown(); void openAssignVDPadLeft(); void openAssignVDPadRight(); void quickAssignVDPadUp(JoyAxisButton *joyaxisbtn); void quickAssignVDPadUpBtn(JoyButton *joybtn); void quickAssignVDPadDown(JoyAxisButton *axbtn); void quickAssignVDPadDownJbtn(JoyButton *axbtn); void quickAssignVDPadLeft(JoyAxisButton *joyaxisbtn); void quickAssignVDPadLeftJbtn(JoyButton *joybtn); void quickAssignVDPadRight(JoyAxisButton *joyaxisbtn); void quickAssignVDPadRightJbtn(JoyButton *joybtn); void reenableButtonEvents(); private: Ui::AdvanceStickAssignmentDialog *ui; Joystick *joystick; void checkForAxisAssignmentSticks(QWidget *comboBox, QComboBox *xAxisComboBox, QComboBox *yAxisComboBox, int controlStickNumber); void refreshSticksForAxes(bool axesExist, int xAxisComboBoxIndex, int yAxisComboBoxIndex, QComboBox *xAxisComboBox, QComboBox *yAxisComboBox, QCheckBox *enabledSticksCheckbox, QPushButton *quickAssignBtn); void refreshVDPadConf(JoyButton *vdpadButton, QComboBox *vpadComboBox); }; #endif // ADVANCESTICKASSIGNMENTDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/advancestickassignmentdialog.ui000066400000000000000000000505131471077622000260000ustar00rootroot00000000000000 AdvanceStickAssignmentDialog 0 0 770 440 0 0 Stick/Pad Assignment true 0 0 0 Sticks DPads Qt::Horizontal QSizePolicy::Fixed 20 20 0 50 false Note: This window is meant for backwards compatibility with profiles made before antimicro 2.0. Since version 2.0, use of the Game Controller Mapping window is preferred. true 75 true %1 (Joystick %2) -1 -1 75 true Stick 1 true Enabled Qt::Vertical QSizePolicy::Fixed 20 20 Qt::Horizontal 40 20 false Assign X Axis: false Y Axis: false Qt::Horizontal QSizePolicy::Fixed 40 10 75 true Stick 2 false Enabled Qt::Vertical QSizePolicy::Fixed 20 20 Qt::Horizontal 40 20 false Assign X Axis: false Y Axis: false 75 true %1 (Joystick %2) 75 true Number of Physical DPads: %1 Qt::Vertical 20 40 -1 75 true Virtual DPad 1 Qt::Vertical QSizePolicy::Fixed 20 11 Enabled Qt::Vertical QSizePolicy::Fixed 20 20 41 20 false Down: false Left: false Right: Up: false false Assign false Assign false Assign false Assign Qt::Vertical QSizePolicy::Fixed 20 20 Qt::Horizontal Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() AdvanceStickAssignmentDialog accept() 252 369 157 274 buttonBox rejected() AdvanceStickAssignmentDialog reject() 320 369 286 274 listWidget currentRowChanged(int) stackedWidget setCurrentIndex(int) 91 116 291 105 AntiMicroX-antimicrox-b300273/src/gui/axiseditdialog.cpp000066400000000000000000000702761471077622000232370ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "axiseditdialog.h" #include "ui_axiseditdialog.h" #include "antkeymapper.h" #include "axisvaluebox.h" #include "buttoneditdialog.h" #include "common.h" #include "event.h" #include "haptictriggerps5.h" #include "inputdevice.h" #include "joyaxis.h" #include "joycontrolstick.h" #include "mousedialog/mouseaxissettingsdialog.h" #include "setaxisthrottledialog.h" #include "setjoystick.h" #include #include AxisEditDialog::AxisEditDialog(JoyAxis *axis, bool keypadUnlocked, QWidget *parent) : QDialog(parent, Qt::Window) , ui(new Ui::AxisEditDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); setAxisThrottleConfirm = new SetAxisThrottleDialog(axis, this); m_axis = axis; this->keypadUnlocked = keypadUnlocked; updateWindowTitleAxisName(); initialThrottleState = axis->getThrottle(); bool actAsTrigger = false; if ((initialThrottleState == static_cast(JoyAxis::PositiveThrottle)) || (initialThrottleState == static_cast(JoyAxis::PositiveHalfThrottle))) { actAsTrigger = true; } if (actAsTrigger) buildTriggerPresetsMenu(); if (axis->hasHapticTrigger()) { buildHapticTriggerMenu(); selectHapticTrigger(); } else { ui->hapticTriggerLabel->setVisible(false); ui->hapticTriggerComboBox->setVisible(false); } ui->deadZoneSlider->setValue(axis->getDeadZone()); ui->deadZoneSpinBox->setValue(axis->getDeadZone()); ui->maxZoneSlider->setValue(axis->getMaxZoneValue()); ui->maxZoneSpinBox->setValue(axis->getMaxZoneValue()); JoyAxisButton *nButton = axis->getNAxisButton(); if (!nButton->getActionName().isEmpty()) { ui->nPushButton->setText(nButton->getActionName()); } else { ui->nPushButton->setText(nButton->getSlotsSummary()); } JoyAxisButton *pButton = axis->getPAxisButton(); if (!pButton->getActionName().isEmpty()) { ui->pPushButton->setText(pButton->getActionName()); } else { ui->pPushButton->setText(pButton->getSlotsSummary()); } int currentThrottle = axis->getThrottle(); if ((currentThrottle == static_cast(JoyAxis::NegativeThrottle)) || (currentThrottle == static_cast(JoyAxis::NegativeHalfThrottle))) { int tempindex = (currentThrottle == static_cast(JoyAxis::NegativeHalfThrottle)) ? 0 : 1; ui->throttleComboBox->setCurrentIndex(tempindex); ui->nPushButton->setEnabled(true); ui->pPushButton->setEnabled(false); } else if ((currentThrottle == static_cast(JoyAxis::PositiveThrottle)) || (currentThrottle == static_cast(JoyAxis::PositiveHalfThrottle))) { int tempindex = (currentThrottle == static_cast(JoyAxis::PositiveThrottle)) ? 3 : 4; ui->throttleComboBox->setCurrentIndex(tempindex); ui->pPushButton->setEnabled(true); ui->nPushButton->setEnabled(false); } ui->axisstatusBox->setDeadZone(axis->getDeadZone()); ui->axisstatusBox->setMaxZone(axis->getMaxZoneValue()); ui->axisstatusBox->setThrottle(axis->getThrottle()); ui->joyValueLabel->setText(QString::number(axis->getCurrentRawValue())); ui->axisstatusBox->setValue(axis->getCurrentRawValue()); if (!actAsTrigger) selectAxisCurrentPreset(); else selectTriggerPreset(); ui->axisNameLineEdit->setText(axis->getAxisName()); connect(ui->presetsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AxisEditDialog::implementPresets); connect(ui->deadZoneSlider, &QSlider::valueChanged, this, &AxisEditDialog::updateDeadZoneBox); connect(ui->deadZoneSlider, &QSlider::valueChanged, this, [this, axis](int deadzone) { ui->axisstatusBox->setDeadZone(axis, deadzone); }); connect(ui->deadZoneSlider, &QSlider::valueChanged, axis, &JoyAxis::setDeadZone); connect(ui->maxZoneSlider, &QSlider::valueChanged, this, &AxisEditDialog::updateMaxZoneBox); connect(ui->maxZoneSlider, &QSlider::valueChanged, this, [this, axis](int deadzone) { ui->axisstatusBox->setMaxZone(axis, deadzone); }); connect(ui->maxZoneSlider, &QSlider::valueChanged, axis, &JoyAxis::setMaxZoneValue); connect(ui->throttleComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AxisEditDialog::updateThrottleUi); connect(ui->throttleComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AxisEditDialog::presetForThrottleChange); connect(axis, &JoyAxis::moved, this, [this, axis](int value) { ui->axisstatusBox->setValue(axis, value); }); connect(axis, &JoyAxis::moved, this, &AxisEditDialog::updateJoyValue); connect(ui->deadZoneSpinBox, static_cast(&QSpinBox::valueChanged), this, &AxisEditDialog::updateDeadZoneSlider); connect(ui->maxZoneSpinBox, static_cast(&QSpinBox::valueChanged), this, &AxisEditDialog::updateMaxZoneSlider); connect(ui->nPushButton, &QPushButton::clicked, this, &AxisEditDialog::openAdvancedNDialog); connect(ui->pPushButton, &QPushButton::clicked, this, &AxisEditDialog::openAdvancedPDialog); connect(ui->mouseSettingsPushButton, &QPushButton::clicked, this, &AxisEditDialog::openMouseSettingsDialog); connect(ui->axisNameLineEdit, &QLineEdit::textEdited, axis, &JoyAxis::setAxisName); connect(axis, &JoyAxis::axisNameChanged, this, &AxisEditDialog::updateWindowTitleAxisName); connect(this, &AxisEditDialog::finished, this, &AxisEditDialog::checkFinalSettings); connect(ui->hapticTriggerComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AxisEditDialog::implementHapticTrigger); } // for tests AxisEditDialog::AxisEditDialog(QWidget *parent) : QDialog(parent, Qt::Window) , ui(new Ui::AxisEditDialog) { } AxisEditDialog::~AxisEditDialog() { delete ui; } void AxisEditDialog::implementPresets(int index) { bool actAsTrigger = false; int currentThrottle = m_axis->getThrottle(); if ((currentThrottle == static_cast(JoyAxis::PositiveThrottle)) || (currentThrottle == static_cast(JoyAxis::PositiveHalfThrottle))) { actAsTrigger = true; } if (actAsTrigger) implementTriggerPresets(index); else implementAxisPresets(index); } void AxisEditDialog::implementAxisPresets(int index) { JoyButtonSlot *nbuttonslot = nullptr; JoyButtonSlot *pbuttonslot = nullptr; PadderCommon::lockInputDevices(); InputDevice *tempDevice = m_axis->getParentSet()->getInputDevice(); QMetaObject::invokeMethod(tempDevice, "haltServices", Qt::BlockingQueuedConnection); switch (index) { case 1: nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); break; case 2: nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); break; case 3: nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); break; case 4: nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); break; case 5: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up), Qt::Key_Up, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down), Qt::Key_Down, JoyButtonSlot::JoyKeyboard, this); break; case 6: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left), Qt::Key_Left, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right), Qt::Key_Right, JoyButtonSlot::JoyKeyboard, this); break; case 7: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W), Qt::Key_W, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S), Qt::Key_S, JoyButtonSlot::JoyKeyboard, this); break; case 8: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A), Qt::Key_A, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D), Qt::Key_D, JoyButtonSlot::JoyKeyboard, this); break; case 9: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); break; case 10: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); break; case 0: case 11: JoyAxisButton *nbutton = m_axis->getNAxisButton(); JoyAxisButton *pbutton = m_axis->getPAxisButton(); QMetaObject::invokeMethod(nbutton, "clearSlotsEventReset"); QMetaObject::invokeMethod(pbutton, "clearSlotsEventReset", Qt::BlockingQueuedConnection); refreshNButtonLabel(); refreshPButtonLabel(); nbutton->buildActiveZoneSummaryString(); pbutton->buildActiveZoneSummaryString(); break; } if (nbuttonslot != nullptr) { JoyAxisButton *button = m_axis->getNAxisButton(); QMetaObject::invokeMethod(button, "clearSlotsEventReset", Q_ARG(bool, false)); QMetaObject::invokeMethod(button, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, nbuttonslot->getSlotCode()), Q_ARG(int, nbuttonslot->getSlotCodeAlias()), Q_ARG(JoyButtonSlot::JoySlotInputAction, nbuttonslot->getSlotMode())); refreshNButtonLabel(); nbuttonslot->deleteLater(); } if (pbuttonslot != nullptr) { JoyAxisButton *button = m_axis->getPAxisButton(); QMetaObject::invokeMethod(button, "clearSlotsEventReset", Q_ARG(bool, false)); QMetaObject::invokeMethod(button, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, pbuttonslot->getSlotCode()), Q_ARG(int, pbuttonslot->getSlotCodeAlias()), Q_ARG(JoyButtonSlot::JoySlotInputAction, pbuttonslot->getSlotMode())); refreshPButtonLabel(); pbuttonslot->deleteLater(); } PadderCommon::unlockInputDevices(); } void AxisEditDialog::updateDeadZoneBox(int value) { ui->deadZoneSpinBox->setValue(value); } void AxisEditDialog::updateMaxZoneBox(int value) { ui->maxZoneSpinBox->setValue(value); } void AxisEditDialog::updateThrottleUi(int index) { int tempthrottle = 0; if ((index == 0) || (index == 1)) { ui->nPushButton->setEnabled(true); ui->pPushButton->setEnabled(false); tempthrottle = (index == 0) ? static_cast(JoyAxis::NegativeHalfThrottle) : static_cast(JoyAxis::NegativeThrottle); } else if (index == 2) { ui->nPushButton->setEnabled(true); ui->pPushButton->setEnabled(true); tempthrottle = static_cast(JoyAxis::NormalThrottle); } else if ((index == 3) || (index == 4)) { ui->pPushButton->setEnabled(true); ui->nPushButton->setEnabled(false); tempthrottle = (index == 3) ? static_cast(JoyAxis::PositiveThrottle) : static_cast(JoyAxis::PositiveHalfThrottle); } m_axis->setThrottle(tempthrottle); ui->axisstatusBox->setThrottle(tempthrottle); } void AxisEditDialog::updateJoyValue(int value) { ui->joyValueLabel->setText(QString::number(value)); } void AxisEditDialog::updateDeadZoneSlider(int value) { if ((value >= GlobalVariables::JoyAxis::AXISMIN) && (value <= GlobalVariables::JoyAxis::AXISMAX)) { ui->deadZoneSlider->setValue(value); } } void AxisEditDialog::updateMaxZoneSlider(int value) { if ((value >= GlobalVariables::JoyAxis::AXISMIN) && (value <= GlobalVariables::JoyAxis::AXISMAX)) { ui->maxZoneSlider->setValue(value); } } void AxisEditDialog::openAdvancedPDialog() { ButtonEditDialog *dialog = new ButtonEditDialog( m_axis->getPAxisButton(), m_axis->getPAxisButton()->getParentSet()->getInputDevice(), keypadUnlocked, this); dialog->show(); connect(dialog, &ButtonEditDialog::finished, this, &AxisEditDialog::refreshPButtonLabel); connect(dialog, &ButtonEditDialog::finished, this, &AxisEditDialog::refreshPreset); } void AxisEditDialog::openAdvancedNDialog() { ButtonEditDialog *dialog = new ButtonEditDialog( m_axis->getNAxisButton(), m_axis->getNAxisButton()->getParentSet()->getInputDevice(), keypadUnlocked, this); dialog->show(); connect(dialog, &ButtonEditDialog::finished, this, &AxisEditDialog::refreshNButtonLabel); connect(dialog, &ButtonEditDialog::finished, this, &AxisEditDialog::refreshPreset); } void AxisEditDialog::refreshNButtonLabel() { ui->nPushButton->setText(m_axis->getNAxisButton()->getSlotsSummary()); } void AxisEditDialog::refreshPButtonLabel() { ui->pPushButton->setText(m_axis->getPAxisButton()->getSlotsSummary()); } void AxisEditDialog::checkFinalSettings() { if (m_axis->getThrottle() != initialThrottleState) setAxisThrottleConfirm->exec(); } void AxisEditDialog::selectAxisCurrentPreset() { JoyAxisButton *naxisbutton = m_axis->getNAxisButton(); QList *naxisslots = naxisbutton->getAssignedSlots(); JoyAxisButton *paxisbutton = m_axis->getPAxisButton(); QList *paxisslots = paxisbutton->getAssignedSlots(); if ((naxisslots->length() == 1) && (paxisslots->length() == 1)) { JoyButtonSlot *nslot = naxisslots->at(0); JoyButtonSlot *pslot = paxisslots->at(0); if ((nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (nslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (pslot->getSlotCode() == JoyButtonSlot::MouseRight)) { ui->presetsComboBox->setCurrentIndex(1); } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (nslot->getSlotCode() == JoyButtonSlot::MouseRight) && (pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (pslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { ui->presetsComboBox->setCurrentIndex(2); } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (nslot->getSlotCode() == JoyButtonSlot::MouseUp) && (pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (pslot->getSlotCode() == JoyButtonSlot::MouseDown)) { ui->presetsComboBox->setCurrentIndex(3); } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (nslot->getSlotCode() == JoyButtonSlot::MouseDown) && (pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (pslot->getSlotCode() == JoyButtonSlot::MouseUp)) { ui->presetsComboBox->setCurrentIndex(4); } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down))) { ui->presetsComboBox->setCurrentIndex(5); } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right))) { ui->presetsComboBox->setCurrentIndex(6); } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S))) { ui->presetsComboBox->setCurrentIndex(7); } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D))) { ui->presetsComboBox->setCurrentIndex(8); } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2))) { ui->presetsComboBox->setCurrentIndex(9); } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6))) { ui->presetsComboBox->setCurrentIndex(10); } else { ui->presetsComboBox->setCurrentIndex(0); } } else if ((naxisslots->length() == 0) && (paxisslots->length() == 0)) { ui->presetsComboBox->setCurrentIndex(11); } else { ui->presetsComboBox->setCurrentIndex(0); } } void AxisEditDialog::selectTriggerPreset() { JoyAxisButton *paxisbutton = m_axis->getPAxisButton(); QList *paxisslots = paxisbutton->getAssignedSlots(); if (paxisslots->length() == 1) { JoyButtonSlot *pslot = paxisslots->at(0); if ((pslot->getSlotMode() == JoyButtonSlot::JoyMouseButton) && (pslot->getSlotCode() == JoyButtonSlot::MouseLB)) { ui->presetsComboBox->setCurrentIndex(1); } else if ((pslot->getSlotMode() == JoyButtonSlot::JoyMouseButton) && (pslot->getSlotCode() == JoyButtonSlot::MouseRB)) { ui->presetsComboBox->setCurrentIndex(2); } else { ui->presetsComboBox->setCurrentIndex(0); } } else if (paxisslots->length() == 0) { ui->presetsComboBox->setCurrentIndex(3); } else { ui->presetsComboBox->setCurrentIndex(0); } } /** * @brief Converts HapticTriggerMode from the current axis to combo box * index and selects to element. */ void AxisEditDialog::selectHapticTrigger() { HapticTriggerModePs5 mode = m_axis->getHapticTrigger()->get_mode(); switch (mode) { case HAPTIC_TRIGGER_NONE: ui->hapticTriggerComboBox->setCurrentIndex(HAPTIC_TRIGGER_NONE_INDEX); return; case HAPTIC_TRIGGER_CLICK: ui->hapticTriggerComboBox->setCurrentIndex(HAPTIC_TRIGGER_CLICK_INDEX); return; case HAPTIC_TRIGGER_RIGID: ui->hapticTriggerComboBox->setCurrentIndex(HAPTIC_TRIGGER_RIGID_INDEX); return; case HAPTIC_TRIGGER_RIGID_GRADIENT: ui->hapticTriggerComboBox->setCurrentIndex(HAPTIC_TRIGGER_RIGID_GRADIENT_INDEX); return; case HAPTIC_TRIGGER_VIBRATION: ui->hapticTriggerComboBox->setCurrentIndex(HAPTIC_TRIGGER_VIBRATION_INDEX); return; } } void AxisEditDialog::implementTriggerPresets(int index) { JoyButtonSlot *pbuttonslot = nullptr; if (index == 1) { pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseLB, JoyButtonSlot::JoyMouseButton, this); } else if (index == 2) { pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseRB, JoyButtonSlot::JoyMouseButton, this); } else if (index == 3) { JoyAxisButton *nbutton = m_axis->getNAxisButton(); JoyAxisButton *pbutton = m_axis->getPAxisButton(); QMetaObject::invokeMethod(nbutton, "clearSlotsEventReset"); QMetaObject::invokeMethod(pbutton, "clearSlotsEventReset", Qt::BlockingQueuedConnection); refreshNButtonLabel(); refreshPButtonLabel(); } if (pbuttonslot != nullptr) { JoyAxisButton *nbutton = m_axis->getNAxisButton(); JoyAxisButton *pbutton = m_axis->getPAxisButton(); if (nbutton->getAssignedSlots()->length() > 0) { QMetaObject::invokeMethod(nbutton, "clearSlotsEventReset", Qt::BlockingQueuedConnection, Q_ARG(bool, false)); refreshNButtonLabel(); } QMetaObject::invokeMethod(pbutton, "clearSlotsEventReset", Q_ARG(bool, false)); QMetaObject::invokeMethod(pbutton, "setAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, pbuttonslot->getSlotCode()), Q_ARG(int, pbuttonslot->getSlotCodeAlias()), Q_ARG(JoyButtonSlot::JoySlotInputAction, pbuttonslot->getSlotMode())); refreshPButtonLabel(); pbuttonslot->deleteLater(); } } void AxisEditDialog::refreshPreset() { // Disconnect event associated with presetsComboBox so a change in the index does not // alter the axis buttons disconnect(ui->presetsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AxisEditDialog::implementPresets); selectAxisCurrentPreset(); // Reconnect the event connect(ui->presetsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AxisEditDialog::implementPresets); } void AxisEditDialog::openMouseSettingsDialog() { ui->mouseSettingsPushButton->setEnabled(false); MouseAxisSettingsDialog *dialog = new MouseAxisSettingsDialog(m_axis, this); dialog->show(); connect(this, &AxisEditDialog::finished, dialog, &MouseAxisSettingsDialog::close); connect(dialog, &MouseAxisSettingsDialog::finished, this, &AxisEditDialog::enableMouseSettingButton); } void AxisEditDialog::enableMouseSettingButton() { ui->mouseSettingsPushButton->setEnabled(true); } void AxisEditDialog::updateWindowTitleAxisName() { QString temp = QString(tr("Set")).append(" "); if (!m_axis->getAxisName().isEmpty()) { temp.append(m_axis->getPartialName(false, true)); } else { temp.append(m_axis->getPartialName()); } if (m_axis->getParentSet()->getIndex() != 0) { int setIndex = m_axis->getParentSet()->getRealIndex(); temp.append(" [").append(tr("Set %1").arg(setIndex)); QString setName = m_axis->getParentSet()->getName(); if (!setName.isEmpty()) temp.append(": ").append(setName); temp.append("]"); } setWindowTitle(temp); } void AxisEditDialog::buildAxisPresetsMenu() { ui->presetsComboBox->clear(); ui->presetsComboBox->addItem(tr("")); ui->presetsComboBox->addItem(tr("Mouse (Horizontal)")); ui->presetsComboBox->addItem(tr("Mouse (Inverted Horizontal)")); ui->presetsComboBox->addItem(tr("Mouse (Vertical)")); ui->presetsComboBox->addItem(tr("Mouse (Inverted Vertical)")); ui->presetsComboBox->addItem(tr("Arrows: Up | Down")); ui->presetsComboBox->addItem(tr("Arrows: Left | Right")); ui->presetsComboBox->addItem(tr("Keys: W | S")); ui->presetsComboBox->addItem(tr("Keys: A | D")); ui->presetsComboBox->addItem(tr("NumPad: KP_8 | KP_2")); ui->presetsComboBox->addItem(tr("NumPad: KP_4 | KP_6")); ui->presetsComboBox->addItem(tr("None")); } void AxisEditDialog::buildTriggerPresetsMenu() { ui->presetsComboBox->clear(); ui->presetsComboBox->addItem(tr("")); ui->presetsComboBox->addItem(tr("Left Mouse Button")); ui->presetsComboBox->addItem(tr("Right Mouse Button")); ui->presetsComboBox->addItem(tr("None")); } void AxisEditDialog::buildHapticTriggerMenu() { ui->hapticTriggerComboBox->clear(); ui->hapticTriggerComboBox->addItem(tr("None")); ui->hapticTriggerComboBox->addItem(tr("Click")); ui->hapticTriggerComboBox->addItem(tr("Rigid")); ui->hapticTriggerComboBox->addItem(tr("Rigid Gradient")); ui->hapticTriggerComboBox->addItem(tr("Vibration")); } void AxisEditDialog::presetForThrottleChange(int index) { Q_UNUSED(index); bool actAsTrigger = false; int currentThrottle = m_axis->getThrottle(); if ((currentThrottle == static_cast(JoyAxis::PositiveThrottle)) || (currentThrottle == static_cast(JoyAxis::PositiveHalfThrottle))) { actAsTrigger = true; } disconnect(ui->presetsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AxisEditDialog::implementPresets); if (actAsTrigger) { buildTriggerPresetsMenu(); selectTriggerPreset(); } else { buildAxisPresetsMenu(); selectAxisCurrentPreset(); } connect(ui->presetsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &AxisEditDialog::implementPresets); } /** * @brief Converts the haptic trigger combo box index to a * HapticTriggerMode and applies it to the current axis. */ void AxisEditDialog::implementHapticTrigger(int index) { HapticTriggerModePs5 mode; switch (static_cast(index)) { case HAPTIC_TRIGGER_NONE_INDEX: mode = HAPTIC_TRIGGER_NONE; break; case HAPTIC_TRIGGER_CLICK_INDEX: mode = HAPTIC_TRIGGER_CLICK; break; case HAPTIC_TRIGGER_RIGID_INDEX: mode = HAPTIC_TRIGGER_RIGID; break; case HAPTIC_TRIGGER_RIGID_GRADIENT_INDEX: mode = HAPTIC_TRIGGER_RIGID_GRADIENT; break; case HAPTIC_TRIGGER_VIBRATION_INDEX: mode = HAPTIC_TRIGGER_VIBRATION; break; } m_axis->setHapticTriggerMode(mode); } AntiMicroX-antimicrox-b300273/src/gui/axiseditdialog.h000066400000000000000000000051741471077622000226770ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef AXISEDITDIALOG_H #define AXISEDITDIALOG_H #include class JoyAxis; class SetAxisThrottleDialog; class QWidget; namespace Ui { class AxisEditDialog; } class AxisEditDialog : public QDialog { Q_OBJECT public: explicit AxisEditDialog(JoyAxis *axis, bool keypadUnlocked, QWidget *parent = 0); AxisEditDialog(QWidget *parent = 0); ~AxisEditDialog(); protected: void selectAxisCurrentPreset(); void selectTriggerPreset(); void selectHapticTrigger(); void buildTriggerPresetsMenu(); void buildAxisPresetsMenu(); void buildHapticTriggerMenu(); private: /** * @brief Haptic trigger combo box indices. */ enum HapticTriggerIndex { HAPTIC_TRIGGER_NONE_INDEX, HAPTIC_TRIGGER_CLICK_INDEX, HAPTIC_TRIGGER_RIGID_INDEX, HAPTIC_TRIGGER_RIGID_GRADIENT_INDEX, HAPTIC_TRIGGER_VIBRATION_INDEX }; Ui::AxisEditDialog *ui; JoyAxis *m_axis; bool keypadUnlocked; SetAxisThrottleDialog *setAxisThrottleConfirm; int initialThrottleState; private slots: void implementAxisPresets(int index); void implementTriggerPresets(int index); void implementPresets(int index); void presetForThrottleChange(int index); void implementHapticTrigger(int index); void updateDeadZoneBox(int value); void updateMaxZoneBox(int value); void updateThrottleUi(int index); void updateJoyValue(int value); void updateDeadZoneSlider(int value); void updateMaxZoneSlider(int value); void openAdvancedPDialog(); void openAdvancedNDialog(); void refreshPButtonLabel(); void refreshNButtonLabel(); void refreshPreset(); void checkFinalSettings(); void openMouseSettingsDialog(); void enableMouseSettingButton(); void updateWindowTitleAxisName(); }; #endif // AXISEDITDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/axiseditdialog.ui000066400000000000000000000374711471077622000230720ustar00rootroot00000000000000 AxisEditDialog 0 0 682 503 0 0 0 0 16777215 16777215 Axis false true 10 1 Presets: false false 12 12 Mouse (Horizontal) Mouse (Inverted Horizontal) Mouse (Vertical) Mouse (Inverted Vertical) Arrows: Up | Down Arrows: Left | Right Keys: W | S Keys: A | D NumPad: KP_8 | KP_2 NumPad: KP_4 | KP_6 None Qt::Vertical QSizePolicy::MinimumExpanding 20 32 0 0 4 0 0 32 0 Set the value to use as the limit for an axis. Useful for a worn out analog stick. 1 32737 32000 Dead Zone: 200 0 Set the value of the dead zone for an axis. 0 32737 100 1000 5000 5000 true Qt::Horizontal false false QSlider::NoTicks 1000 0 0 32 0 Set the value of the dead zone for an axis. 1 32737 5000 Set the value to use as the limit for an axis. Useful for a worn out analog stick. 0 32737 100 1000 32000 Qt::Horizontal QSlider::NoTicks 1000 Max Zone: Qt::Vertical QSizePolicy::MinimumExpanding 20 32 150 0 [NO KEY] 150 0 [NO KEY] 0 0 350 0 Throttle setting that determines the behavior of how to interpret an axis hold or release. 2 5 5 Negative Half Throttle Negative Throttle Normal Positive Throttle Positive Half Throttle Haptic Trigger: Qt::Vertical QSizePolicy::MinimumExpanding 20 32 0 0 0 25 16777215 25 10 0 0 Current Value: 0 4 0 0 Qt::Vertical QSizePolicy::MinimumExpanding 20 32 Name: axisNameLineEdit Specify the name of an axis. Mouse Settings .. Qt::Horizontal Qt::Horizontal QDialogButtonBox::Close false AxisValueBox QWidget
axisvaluebox.h
1
buttonBox accepted() AxisEditDialog accept() 248 254 157 274 buttonBox rejected() AxisEditDialog reject() 316 260 286 274
AntiMicroX-antimicrox-b300273/src/gui/buttoneditdialog.cpp000066400000000000000000000551051471077622000236000ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "buttoneditdialog.h" #include "ui_buttoneditdialog.h" #include "advancebuttondialog.h" #include "inputdevice.h" #include "joybuttontypes/joybutton.h" #include "keyboard/virtualkeyboardmousewidget.h" #include "quicksetdialog.h" #include "antkeymapper.h" #include "common.h" #include "event.h" #include "eventhandlerfactory.h" #include "inputdevice.h" #include "setjoystick.h" #include #include #include #include #include #include #include #ifdef Q_OS_WIN #include "winextras.h" #include #endif ButtonEditDialog *ButtonEditDialog::instance = nullptr; ButtonEditDialog::ButtonEditDialog(InputDevice *joystick, bool isNumKeypad, QWidget *parent) : QDialog(parent, Qt::Window) , helper() , ui(new Ui::ButtonEditDialog) { ui->setupUi(this); withoutQuickSetDialog = false; m_isNumKeypad = isNumKeypad; ui->attachNumKeypadCheckbox->setChecked(isNumKeypad); setAttribute(Qt::WA_DeleteOnClose); setWindowTitle(tr("Choose your keyboard key")); update(); instance = this; this->joystick = joystick; lastJoyButton = nullptr; currentQuickDialog = nullptr; SetJoystick *currentset = joystick->getActiveSetJoystick(); currentset->release(); joystick->resetButtonDownCount(); setAttribute(Qt::WA_DeleteOnClose); setWindowModality(Qt::WindowModal); ignoreRelease = false; setupVirtualKeyboardMouseTabWidget(); connect(qApp, &QApplication::focusChanged, this, &ButtonEditDialog::checkForKeyboardWidgetFocus); connect(this, &ButtonEditDialog::keyGrabbed, this, &ButtonEditDialog::processSlotAssignment); connect(this, &ButtonEditDialog::selectionCleared, this, &ButtonEditDialog::clearButtonSlots); // used to clear button sets connect(ui->toggleCheckBox, &QCheckBox::clicked, this, &ButtonEditDialog::changeToggleSetting); connect(ui->turboCheckBox, &QCheckBox::clicked, this, &ButtonEditDialog::changeTurboSetting); connect(ui->attachNumKeypadCheckbox, &QCheckBox::clicked, this, &ButtonEditDialog::changeNumKeypadSetting); connect(ui->advancedPushButton, &QPushButton::clicked, this, &ButtonEditDialog::openAdvancedDialog); refreshForLastBtn(); } ButtonEditDialog::ButtonEditDialog(JoyButton *button, InputDevice *joystick, bool isNumKeypad, QWidget *parent) : ButtonEditDialog(joystick, isNumKeypad, parent) { withoutQuickSetDialog = true; lastJoyButton = button; setupVirtualKeyboardMouseTabWidget(); refreshForLastBtn(); } // for tests ButtonEditDialog::ButtonEditDialog(QWidget *parent) : QDialog(parent, Qt::Window) , helper() , ui(new Ui::ButtonEditDialog) { } ButtonEditDialog *ButtonEditDialog::getInstance() { return instance; } void ButtonEditDialog::checkForKeyboardWidgetFocus(QWidget *old, QWidget *now) { Q_UNUSED(old); Q_UNUSED(now); if (ui->virtualKeyMouseTabWidget->hasFocus() && ui->virtualKeyMouseTabWidget->isKeyboardTabVisible()) { grabKeyboard(); } else { releaseKeyboard(); } } ButtonEditDialog::~ButtonEditDialog() { instance = nullptr; delete ui; } void ButtonEditDialog::keyPressEvent(QKeyEvent *event) { bool ignore = false; // Ignore the following keys that might // trigger an event in QDialog::keyPressEvent switch (event->key()) { case Qt::Key_Escape: case Qt::Key_Right: case Qt::Key_Down: case Qt::Key_Up: case Qt::Key_Left: case Qt::Key_Enter: case Qt::Key_Return: { ignore = true; break; } default: break; } if (!ignore) QDialog::keyPressEvent(event); } void ButtonEditDialog::setupVirtualKeyboardMouseTabWidget() { PadderCommon::inputDaemonMutex.lock(); ui->virtualKeyMouseTabWidget->hide(); ui->virtualKeyMouseTabWidget->deleteLater(); ui->virtualKeyMouseTabWidget = new VirtualKeyboardMouseWidget(joystick, &helper, m_isNumKeypad, currentQuickDialog, lastJoyButton, this); ui->verticalLayout->insertWidget(1, ui->virtualKeyMouseTabWidget); PadderCommon::inputDaemonMutex.unlock(); connect(ui->virtualKeyMouseTabWidget, &VirtualKeyboardMouseWidget::selectionCleared, this, &ButtonEditDialog::refreshSlotSummaryLabel); connect(this, &ButtonEditDialog::advancedDialogOpened, ui->virtualKeyMouseTabWidget, &VirtualKeyboardMouseWidget::establishVirtualKeyboardAdvancedSignalConnections); connect(this, &ButtonEditDialog::advancedDialogOpened, ui->virtualKeyMouseTabWidget, &VirtualKeyboardMouseWidget::establishVirtualMouseAdvancedSignalConnections); } void ButtonEditDialog::keyReleaseEvent(QKeyEvent *event) { qDebug() << "It's keyrelease event"; if (ui->actionNameLineEdit->hasFocus() || ui->buttonNameLineEdit->hasFocus()) { QDialog::keyReleaseEvent(event); } else if (ui->virtualKeyMouseTabWidget->isKeyboardTabVisible()) { int controlcode = event->nativeScanCode(); int virtualactual = event->nativeVirtualKey(); BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); int finalvirtual = 0; int checkalias = 0; #ifdef Q_OS_WIN #ifdef WITH_VMULTI if (handler->getIdentifier() == "vmulti") { finalvirtual = WinExtras::correctVirtualKey(controlcode, virtualactual); checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); // unsigned int tempQtKey = nativeWinKeyMapper.returnQtKey(finalvirtual); QtKeyMapperBase *nativeWinKeyMapper = AntKeyMapper::getInstance()->getNativeKeyMapper(); unsigned int tempQtKey = 0; if (nativeWinKeyMapper) { tempQtKey = nativeWinKeyMapper->returnQtKey(finalvirtual); } if (tempQtKey > 0) { finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey(tempQtKey); checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); } else { finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey(event->key()); } } #endif BACKEND_ELSE_IF(handler->getIdentifier() == "sendinput") { // Find more specific virtual key (VK_SHIFT -> VK_LSHIFT) // by checking for extended bit in scan code. finalvirtual = WinExtras::correctVirtualKey(controlcode, virtualactual); checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual, controlcode); } #else #if defined(WITH_X11) if (QApplication::platformName() == QStringLiteral("xcb")) { // Obtain group 1 X11 keysym. Removes effects from modifiers. finalvirtual = X11KeyCodeToX11KeySym(controlcode); #ifdef WITH_UINPUT if (handler->getIdentifier() == "uinput") { // Find Qt Key corresponding to X11 KeySym. Q_ASSERT(AntKeyMapper::getInstance()->hasNativeKeyMapper()); QtKeyMapperBase *x11KeyMapper = AntKeyMapper::getInstance()->getNativeKeyMapper(); Q_ASSERT(x11KeyMapper != nullptr); checkalias = x11KeyMapper->returnQtKey(finalvirtual); finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey( checkalias); // Find corresponding Linux input key for the Qt key. } #endif #ifdef WITH_XTEST BACKEND_ELSE_IF(handler->getIdentifier() == "xtest") { // Check for alias against group 1 keysym. checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); } #endif } else { // Not running on xcb platform. finalvirtual = controlcode; checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); } #else finalvirtual = 0; checkalias = 0; if (QApplication::platformName() == QStringLiteral("xcb")) { finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey(event->key()); checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); } else { // Not running on xcb platform. finalvirtual = controlcode; checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); } #endif #endif if (!ignoreRelease && (event->modifiers() & Qt::ControlModifier) && (event->key() == Qt::Key_X)) { controlcode = 0; ignoreRelease = true; emit selectionCleared(); } else if (!ignoreRelease && (controlcode <= 0)) { controlcode = 0; } else if (ignoreRelease) { controlcode = 0; ignoreRelease = false; } if (controlcode > 0 && (checkalias > 0) && (finalvirtual > 0)) { JoyButtonSlot *tempslot = new JoyButtonSlot(finalvirtual, checkalias, JoyButtonSlot::JoyKeyboard, this); emit keyGrabbed(tempslot); } else if ((controlcode > 0) && (virtualactual > 0)) { JoyButtonSlot *tempslot = new JoyButtonSlot(virtualactual, JoyButtonSlot::JoyKeyboard, this); emit keyGrabbed(tempslot); } else { QDialog::keyReleaseEvent(event); } } else { QDialog::keyReleaseEvent(event); } } void ButtonEditDialog::refreshSlotSummaryLabel() { if (lastJoyButton != nullptr) ui->slotSummaryLabel->setText(lastJoyButton->getSlotsString().replace("&", "&&")); else ui->slotSummaryLabel->setText(tr("No button")); } void ButtonEditDialog::changeToggleSetting() { if (lastJoyButton != nullptr) lastJoyButton->setToggle(ui->toggleCheckBox->isChecked()); else QMessageBox::information( this, tr("Last button"), tr("To change settings for last button, it must be at least one assignment from keyboard to gamepad")); } void ButtonEditDialog::changeTurboSetting() { if (lastJoyButton != nullptr) lastJoyButton->setUseTurbo(ui->turboCheckBox->isChecked()); else QMessageBox::information( this, tr("Last button"), tr("To change settings of turbo for last button, it must be at least one assignment from keyboard to gamepad")); } void ButtonEditDialog::changeNumKeypadSetting() { m_isNumKeypad = ui->attachNumKeypadCheckbox->isChecked(); setupVirtualKeyboardMouseTabWidget(); refreshForLastBtn(); joystick->getSettings()->setValue("AttachNumKeypad", m_isNumKeypad ? "1" : "0"); } void ButtonEditDialog::openAdvancedDialog() { if (lastJoyButton != nullptr) { if (lastJoyButton->getAssignedSlots()->count() > 0) { AdvanceButtonDialog *dialog = new AdvanceButtonDialog(lastJoyButton, this); dialog->show(); // Disconnect event to allow for placing slot to AdvanceButtonDialog disconnect(this, &ButtonEditDialog::keyGrabbed, nullptr, nullptr); disconnect(this, &ButtonEditDialog::selectionCleared, nullptr, nullptr); disconnect(this, &ButtonEditDialog::selectionFinished, nullptr, nullptr); connect(dialog, &AdvanceButtonDialog::finished, ui->virtualKeyMouseTabWidget, &VirtualKeyboardMouseWidget::establishVirtualKeyboardSingleSignalConnections); connect(dialog, &AdvanceButtonDialog::finished, ui->virtualKeyMouseTabWidget, &VirtualKeyboardMouseWidget::establishVirtualMouseSignalConnections); connect(dialog, &AdvanceButtonDialog::finished, this, &ButtonEditDialog::closedAdvancedDialog); connect(dialog, &AdvanceButtonDialog::turboButtonEnabledChange, this, &ButtonEditDialog::setTurboButtonEnabled); connect(this, &ButtonEditDialog::sendTempSlotToAdvanced, dialog, &AdvanceButtonDialog::placeNewSlot); connect(this, &ButtonEditDialog::keyGrabbed, dialog, &AdvanceButtonDialog::placeNewSlot); connect(this, &ButtonEditDialog::selectionCleared, dialog, &AdvanceButtonDialog::clearAllSlots); connect(ui->virtualKeyMouseTabWidget, static_cast( &VirtualKeyboardMouseWidget::selectionMade), dialog, &AdvanceButtonDialog::placeNewSlot); connect(ui->virtualKeyMouseTabWidget, static_cast(&VirtualKeyboardMouseWidget::selectionMade), this, &ButtonEditDialog::createTempSlot); connect(ui->virtualKeyMouseTabWidget, &VirtualKeyboardMouseWidget::selectionCleared, dialog, &AdvanceButtonDialog::clearAllSlots); connect(this, &ButtonEditDialog::finished, dialog, &AdvanceButtonDialog::close); emit advancedDialogOpened(); } else { QMessageBox::information(this, tr("No choice"), tr("Before you open window with advanced settings, you have to choice a key")); } } else { QMessageBox::information( this, tr("Last button"), tr("To open advanced dialog, it's needed to map at least one button from keyboard to gamepad")); } } void ButtonEditDialog::createTempSlot(int keycode, int alias) { JoyButtonSlot *slot = new JoyButtonSlot(keycode, alias, JoyButtonSlot::JoyKeyboard, this); emit sendTempSlotToAdvanced(slot); } void ButtonEditDialog::checkTurboSetting(bool state) { if (lastJoyButton != nullptr) { if (lastJoyButton->containsSequence()) { ui->turboCheckBox->setChecked(false); ui->turboCheckBox->setEnabled(false); } else { ui->turboCheckBox->setChecked(state); ui->turboCheckBox->setEnabled(true); } } } void ButtonEditDialog::setTurboButtonEnabled(bool state) { ui->turboCheckBox->setEnabled(state); } void ButtonEditDialog::closedAdvancedDialog() { refreshForLastBtn(); disconnect(ui->virtualKeyMouseTabWidget, static_cast(&VirtualKeyboardMouseWidget::selectionMade), this, nullptr); // Re-connect previously disconnected event connect(this, &ButtonEditDialog::keyGrabbed, this, &ButtonEditDialog::processSlotAssignment); connect(this, &ButtonEditDialog::selectionCleared, this, &ButtonEditDialog::clearButtonSlots); connect(this, &ButtonEditDialog::selectionCleared, this, &ButtonEditDialog::sendSelectionFinished); } void ButtonEditDialog::processSlotAssignment(JoyButtonSlot *tempslot) { if (withoutQuickSetDialog) { invokeMethodLastBtn(lastJoyButton, &helper, "setAssignedSlot", tempslot->getSlotCode(), tempslot->getSlotCodeAlias(), -1, tempslot->getSlotMode(), false, false, Qt::QueuedConnection, Qt::QueuedConnection, Qt::QueuedConnection); } else { if ((currentQuickDialog == nullptr) && (!buttonEventInterval.isValid() || (buttonEventInterval.elapsed() > 1000))) { // for better security, force pausing for 1 sec between key presses, // because mapped joystick buttons and axes become keys too // it's good for oversensitive buttons and axes, which can // create QuickSetDialog windows many times for one key if (!buttonEventInterval.isValid()) buttonEventInterval.start(); else buttonEventInterval.restart(); currentQuickDialog = new QuickSetDialog(joystick, &helper, "setAssignedSlot", tempslot->getSlotCode(), tempslot->getSlotCodeAlias(), -1, tempslot->getSlotMode(), false, false, this); currentQuickDialog->show(); connect(currentQuickDialog, &QuickSetDialog::finished, this, &ButtonEditDialog::nullifyDialogPointer); } } tempslot->deleteLater(); } void ButtonEditDialog::clearButtonSlots() { if (lastJoyButton != nullptr) QMetaObject::invokeMethod(lastJoyButton, "clearSlotsEventReset", Q_ARG(bool, false)); else QMessageBox::information(this, tr("Last button"), tr("Slots for button couldn't be cleared, because there was not any set button from " "keyboard for gamepad. Map at least one button from keyboard to gamepad")); } void ButtonEditDialog::sendSelectionFinished() { emit selectionFinished(); } void ButtonEditDialog::updateWindowTitleButtonName() { if (lastJoyButton != nullptr) { QString temp = QString(tr("As last gamepad button has been set")) .append(" \"") .append(lastJoyButton->getPartialName(false, true)) .append("\" "); if (lastJoyButton->getParentSet()->getIndex() != 0) { int setIndex = lastJoyButton->getParentSet()->getRealIndex(); temp.append(" [").append(tr("Index %1").arg(setIndex)); QString setName = lastJoyButton->getParentSet()->getName(); if (!setName.isEmpty()) temp.append(": ").append(setName); temp.append("]"); } setWindowTitle(temp); } else { setWindowTitle(tr("Choose your keyboard key")); } } void ButtonEditDialog::nullifyDialogPointer() { if (currentQuickDialog != nullptr) { lastJoyButton = currentQuickDialog->getLastPressedButton(); currentQuickDialog = nullptr; emit buttonDialogClosed(); } refreshForLastBtn(); } void ButtonEditDialog::refreshForLastBtn() { if (lastJoyButton != nullptr) { ui->slotSummaryLabel->setText(lastJoyButton->getSlotsString()); updateWindowTitleButtonName(); ui->toggleCheckBox->setChecked(lastJoyButton->getToggleState()); ui->turboCheckBox->setChecked(lastJoyButton->isUsingTurbo()); if (!lastJoyButton->getActionName().isEmpty()) ui->actionNameLineEdit->setText(lastJoyButton->getActionName()); if (!lastJoyButton->getButtonName().isEmpty()) ui->buttonNameLineEdit->setText(lastJoyButton->getButtonName()); if (lastJoyButton != nullptr) { QListIterator iter(*(lastJoyButton->getAssignedSlots())); ui->virtualKeyMouseTabWidget->disableMouseSettingButton(); while (iter.hasNext()) { JoyButtonSlot *buttonslot = iter.next(); switch (buttonslot->getSlotMode()) { case JoyButtonSlot::JoyMouseMovement: case JoyButtonSlot::JoyMouseButton: ui->virtualKeyMouseTabWidget->enableMouseSettingButton(); break; default: break; } } } connect(ui->actionNameLineEdit, &QLineEdit::textEdited, lastJoyButton, &JoyButton::setActionName); connect(ui->buttonNameLineEdit, &QLineEdit::textEdited, lastJoyButton, &JoyButton::setButtonName); connect(lastJoyButton, &JoyButton::toggleChanged, ui->toggleCheckBox, &QCheckBox::setChecked); connect(lastJoyButton, &JoyButton::turboChanged, this, &ButtonEditDialog::checkTurboSetting); connect(lastJoyButton, &JoyButton::slotsChanged, this, &ButtonEditDialog::refreshSlotSummaryLabel); connect(lastJoyButton, &JoyButton::buttonNameChanged, this, &ButtonEditDialog::updateWindowTitleButtonName); } update(); } void ButtonEditDialog::invokeMethodLastBtn(JoyButton *lastJoyBtn, ButtonEditDialogHelper *helper, const char *invokeString, int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode, bool withClear, bool withTrue, Qt::ConnectionType connTypeForAlias, Qt::ConnectionType connTypeForNothing, Qt::ConnectionType connTypeForAll) { QPointer lastBtn = lastJoyBtn; if (helper != nullptr) helper = new ButtonEditDialogHelper(); QPointer btnEditDHelper = helper; if (lastJoyBtn != nullptr) { helper->setThisButton(lastJoyBtn); helper->moveToThread(lastJoyBtn->thread()); if (withClear) QMetaObject::invokeMethod(lastJoyBtn, "clearSlotsEventReset", Q_ARG(bool, withTrue)); // when alias exists but not index if ((alias != -1) && (index == -1)) { QMetaObject::invokeMethod(helper, invokeString, connTypeForAlias, Q_ARG(int, code), Q_ARG(int, alias), Q_ARG(JoyButtonSlot::JoySlotInputAction, mode)); // when alias doesn't exists and index too } else if ((alias == -1) && (index == -1)) { QMetaObject::invokeMethod(helper, invokeString, connTypeForNothing, Q_ARG(int, code), Q_ARG(JoyButtonSlot::JoySlotInputAction, mode)); // when all exist (code, alias, index) } else { if (lastJoyBtn->isPartVDPad()) connTypeForAll = Qt::BlockingQueuedConnection; QMetaObject::invokeMethod(helper, invokeString, connTypeForAll, Q_ARG(int, code), Q_ARG(int, alias), Q_ARG(int, index), Q_ARG(JoyButtonSlot::JoySlotInputAction, mode)); } } if (lastBtn.isNull()) lastBtn.clear(); if (btnEditDHelper.isNull()) btnEditDHelper.clear(); } JoyButton *ButtonEditDialog::getLastJoyButton() { return lastJoyButton; } void ButtonEditDialog::setUpLastJoyButton(JoyButton *newButton) { lastJoyButton = newButton; } ButtonEditDialogHelper &ButtonEditDialog::getHelperLocal() { return helper; } AntiMicroX-antimicrox-b300273/src/gui/buttoneditdialog.h000066400000000000000000000067741471077622000232550ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BUTTONEDITDIALOGTWO_H #define BUTTONEDITDIALOGTWO_H #include #include "uihelpers/buttoneditdialoghelper.h" class JoyButton; class JoyButtonSlot; class QWidget; class QKeyEvent; class InputDevice; class QuickSetDialog; namespace Ui { class ButtonEditDialog; } class ButtonEditDialog : public QDialog { Q_OBJECT public: explicit ButtonEditDialog(JoyButton *button, InputDevice *joystick, bool isNumKeypad, QWidget *parent = nullptr); // called for chosen button explicit ButtonEditDialog(InputDevice *joystick, bool isNumKeypad, QWidget *parent = nullptr); // Accessed by pressing the "Quick Set" button ButtonEditDialog(QWidget *parent = 0); ~ButtonEditDialog(); static ButtonEditDialog *getInstance(); JoyButton *getLastJoyButton(); void setUpLastJoyButton(JoyButton *); void refreshForLastBtn(); void invokeMethodLastBtn(JoyButton *lastJoyBtn, ButtonEditDialogHelper *helper, const char *invokeString, int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode, bool withClear, bool withTrue, Qt::ConnectionType connTypeForAlias, Qt::ConnectionType connTypeForNothing, Qt::ConnectionType connTypeForAll); protected: virtual void keyReleaseEvent(QKeyEvent *event); virtual void keyPressEvent(QKeyEvent *event); private: void setupVirtualKeyboardMouseTabWidget(); ButtonEditDialogHelper helper; Ui::ButtonEditDialog *ui; ButtonEditDialogHelper &getHelperLocal(); QElapsedTimer buttonEventInterval; InputDevice *joystick; QuickSetDialog *currentQuickDialog; bool ignoreRelease; bool withoutQuickSetDialog; bool m_isNumKeypad; JoyButton *lastJoyButton; static ButtonEditDialog *instance; signals: void advancedDialogOpened(); void sendTempSlotToAdvanced(JoyButtonSlot *tempslot); void keyGrabbed(JoyButtonSlot *tempslot); void selectionCleared(); void selectionFinished(); void buttonDialogClosed(); private slots: void nullifyDialogPointer(); void refreshSlotSummaryLabel(); void changeToggleSetting(); void changeTurboSetting(); void changeNumKeypadSetting(); void openAdvancedDialog(); void closedAdvancedDialog(); void createTempSlot(int keycode, int alias); void checkTurboSetting(bool state); void setTurboButtonEnabled(bool state); void processSlotAssignment(JoyButtonSlot *tempslot); void clearButtonSlots(); void sendSelectionFinished(); void updateWindowTitleButtonName(); void checkForKeyboardWidgetFocus(QWidget *old, QWidget *now); }; #endif // BUTTONEDITDIALOGTWO_H AntiMicroX-antimicrox-b300273/src/gui/buttoneditdialog.ui000066400000000000000000000225551471077622000234360ustar00rootroot00000000000000 ButtonEditDialog Qt::WindowModal 0 0 800 600 800 600 Dialog false false 0 0 1 To make a new assignment, press any keyboard key or click a button in the Keyboard or Mouse tab false Qt::AlignCenter true QTabWidget::South 0 false Placeholder Qt::Vertical QSizePolicy::Fixed 20 4 Enables a key press or release to only occur when a controller button is pressed. Toggle Qt::Horizontal QSizePolicy::Fixed 20 20 Enables rapid key presses and releases. Turbo controller. Turbo Qt::Horizontal QSizePolicy::Fixed 20 20 Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs Attach the numeric keypad Qt::Horizontal QSizePolicy::Expanding 20 20 75 true Last keyboard/mouse button: Slots false 30 6 6 4 Na&me: buttonNameLineEdit Specify the name of a button. 20 4 Action: actionNameLineEdit Specify the action that will be performed in game while this button is being used. 50 Qt::Horizontal 4 Advanced .. Qt::Horizontal QDialogButtonBox::Close VirtualKeyboardMouseWidget QTabWidget
keyboard/virtualkeyboardmousewidget.h
1
buttonBox accepted() ButtonEditDialog accept() 366 422 157 274 buttonBox rejected() ButtonEditDialog reject() 434 422 286 274
AntiMicroX-antimicrox-b300273/src/gui/calibration.cpp000066400000000000000000000716371471077622000225360ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "calibration.h" #include "ui_calibration.h" #include "globalvariables.h" #include "inputdevice.h" #include "joycontrolstick.h" #include "joysensor.h" #include #include #include const int Calibration::CAL_MIN_SAMPLES = 10; // Use squared accuracy to avoid root calculation. 1e-4 corresponds to an accuracy of 1%. const double Calibration::CAL_ACCURACY_SQ = 1e-4; const double Calibration::STICK_CAL_TAU = 0.045; const int Calibration::STICK_RATE_SAMPLES = 100; const int Calibration::CAL_TIMEOUT = 30; Calibration::Calibration(InputDevice *joystick, QDialog *parent) : QDialog(parent) , m_ui(new Ui::Calibration) , m_type(CAL_NONE) , m_calibrated(false) , m_changed(false) , m_joystick(joystick) { m_ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose, true); setWindowTitle(tr("Calibration")); hideCalibrationData(); int device_count = 0; QMap dropdown_sticks; QHash sticks = m_joystick->getActiveSetJoystick()->getSticks(); for (auto iter = sticks.cbegin(); iter != sticks.cend(); ++iter) { dropdown_sticks.insert(iter.value()->getPartialName(), CAL_STICK | (iter.key() << CAL_INDEX_POS)); } for (auto iter = dropdown_sticks.cbegin(); iter != dropdown_sticks.cend(); ++iter) { m_ui->deviceComboBox->addItem(iter.key(), QVariant(int(iter.value()))); ++device_count; } if (m_joystick->getActiveSetJoystick()->hasSensor(GYROSCOPE)) { m_ui->deviceComboBox->addItem(tr("Gyroscope"), QVariant(int(CAL_GYROSCOPE))); ++device_count; } if (m_joystick->getActiveSetJoystick()->hasSensor(ACCELEROMETER)) { m_ui->deviceComboBox->addItem(tr("Accelerometer"), QVariant(int(CAL_ACCELEROMETER))); ++device_count; } connect(m_joystick, &InputDevice::destroyed, this, &Calibration::close); connect(m_ui->resetBtn, &QPushButton::clicked, this, &Calibration::resetSettings); connect(m_ui->saveBtn, &QPushButton::clicked, this, &Calibration::saveSettings); connect(m_ui->cancelBtn, &QPushButton::clicked, this, &Calibration::close); connect(m_ui->deviceComboBox, static_cast(&QComboBox::currentIndexChanged), this, &Calibration::deviceSelectionChanged); if (device_count == 0) { m_ui->steps->setText(tr("Selected device doesn't have any inputs to calibrate.")); } else { int index = m_ui->deviceComboBox->currentIndex(); unsigned int data = m_ui->deviceComboBox->itemData(index).toInt(); selectTypeIndex(data); } update(); } Calibration::~Calibration() { delete m_ui; } /** * @brief Ask for confirmation when the dialog is closed with unsafed changed. */ void Calibration::closeEvent(QCloseEvent *event) { event->ignore(); if (m_changed) { if (askConfirmation(tr("Calibration was not saved for the preset. Do you really want to continue?"), false)) { event->accept(); } } else { event->accept(); } } /** * @brief Asks for confirmation and resets calibration values of the selected device * afterwards. */ void Calibration::resetSettings() { QMessageBox msgBox; msgBox.setText(tr("Do you really want to reset calibration of current device?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); switch (msgBox.exec()) { case QMessageBox::Yes: resetCalibrationValues(); m_ui->steps->clear(); break; case QMessageBox::No: break; default: break; } } /** * @brief Shows the sensor offset calibration values to the user. */ void Calibration::showSensorCalibrationValues(bool offsetXvalid, double offsetX, bool offsetYvalid, double offsetY, bool offsetZvalid, double offsetZ) { QPalette paletteBlack = m_ui->offsetXValue->palette(); paletteBlack.setColor(m_ui->offsetXValue->foregroundRole(), Qt::black); QPalette paletteRed = m_ui->offsetXValue->palette(); paletteRed.setColor(m_ui->offsetXValue->foregroundRole(), Qt::red); m_ui->offsetXValue->setPalette(offsetXvalid ? paletteBlack : paletteRed); m_ui->offsetYValue->setPalette(offsetYvalid ? paletteBlack : paletteRed); m_ui->offsetZValue->setPalette(offsetZvalid ? paletteBlack : paletteRed); if (m_type == CAL_ACCELEROMETER) { m_ui->offsetXValue->setText(QString::number(offsetX)); m_ui->offsetYValue->setText(QString::number(offsetY)); m_ui->offsetZValue->setText(QString::number(offsetZ)); } else if (m_type == CAL_GYROSCOPE) { m_ui->offsetXValue->setText(QString::number(JoySensor::radToDeg(offsetX))); m_ui->offsetYValue->setText(QString::number(JoySensor::radToDeg(offsetY))); m_ui->offsetZValue->setText(QString::number(JoySensor::radToDeg(offsetZ))); } } /** * @brief Shows the stick offset and gain calibration values to the user. */ void Calibration::showStickCalibrationValues(bool offsetXvalid, double offsetX, bool gainXvalid, double gainX, bool offsetYvalid, double offsetY, bool gainYvalid, double gainY) { QPalette paletteBlack = m_ui->offsetXValue->palette(); paletteBlack.setColor(m_ui->offsetXValue->foregroundRole(), Qt::black); QPalette paletteRed = m_ui->offsetXValue->palette(); paletteRed.setColor(m_ui->offsetXValue->foregroundRole(), Qt::red); m_ui->offsetXValue->setPalette(offsetXvalid ? paletteBlack : paletteRed); m_ui->gainXValue->setPalette(gainXvalid ? paletteBlack : paletteRed); m_ui->offsetYValue->setPalette(offsetYvalid ? paletteBlack : paletteRed); m_ui->gainYValue->setPalette(gainYvalid ? paletteBlack : paletteRed); m_ui->offsetXValue->setText(QString::number(offsetX)); m_ui->gainXValue->setText(QString::number(gainX)); m_ui->offsetYValue->setText(QString::number(offsetY)); m_ui->gainYValue->setText(QString::number(gainY)); } /** * @brief hides all calibration values and their labels. */ void Calibration::hideCalibrationData() { m_ui->xAxisLabel->setVisible(false); m_ui->yAxisLabel->setVisible(false); m_ui->zAxisLabel->setVisible(false); m_ui->offsetXLabel->setVisible(false); m_ui->offsetYLabel->setVisible(false); m_ui->offsetZLabel->setVisible(false); m_ui->offsetXValue->setVisible(false); m_ui->offsetYValue->setVisible(false); m_ui->offsetZValue->setVisible(false); m_ui->gainXLabel->setVisible(false); m_ui->gainYLabel->setVisible(false); m_ui->gainZLabel->setVisible(false); m_ui->gainXValue->setVisible(false); m_ui->gainYValue->setVisible(false); m_ui->gainZValue->setVisible(false); m_ui->steps->clear(); } /** * @brief Prepares calibration for the selected device type. * Show all used values and labels and connect buttons to the corresponding * event handlers. */ void Calibration::selectTypeIndex(unsigned int type_index) { CalibrationType type = static_cast(type_index & CAL_TYPE_MASK); unsigned int index = (type_index & CAL_INDEX_MASK) >> CAL_INDEX_POS; if (m_type == type && m_index == index) return; disconnect(m_ui->startBtn, &QPushButton::clicked, this, nullptr); m_type = type; m_index = index; m_changed = false; hideCalibrationData(); if (m_type == CAL_STICK) { m_ui->statusStack->setCurrentIndex(1); m_stick = m_joystick->getActiveSetJoystick()->getSticks().value(m_index); m_calibrated = m_stick->isCalibrated(); if (m_calibrated) { double offsetX, gainX, offsetY, gainY; m_stick->getCalibration(&offsetX, &gainX, &offsetY, &gainY); showStickCalibrationValues(true, offsetX, true, gainX, true, offsetY, true, gainY); } else { showStickCalibrationValues(false, 0.0, false, 1.0, false, 0.0, false, 1.0); } m_ui->xAxisLabel->setVisible(true); m_ui->yAxisLabel->setVisible(true); m_ui->offsetXLabel->setVisible(true); m_ui->offsetYLabel->setVisible(true); m_ui->offsetXValue->setVisible(true); m_ui->offsetYValue->setVisible(true); m_ui->gainXLabel->setVisible(true); m_ui->gainYLabel->setVisible(true); m_ui->gainXValue->setVisible(true); m_ui->gainYValue->setVisible(true); m_ui->resetBtn->setEnabled(m_calibrated); m_ui->saveBtn->setEnabled(false); m_ui->stickStatusBoxWidget->setFocus(); m_ui->stickStatusBoxWidget->setStick(m_stick); m_ui->stickStatusBoxWidget->update(); connect(m_ui->startBtn, &QPushButton::clicked, this, &Calibration::startStickOffsetCalibration); m_ui->startBtn->setEnabled(true); m_ui->resetBtn->setEnabled(true); } else if (m_type == CAL_ACCELEROMETER || m_type == CAL_GYROSCOPE) { if (m_type == CAL_ACCELEROMETER) { m_sensor = m_joystick->getActiveSetJoystick()->getSensor(ACCELEROMETER); m_ui->steps->setText(tr("Accelerometer calibration sets the neutral controller orientation.")); connect(m_ui->startBtn, &QPushButton::clicked, this, &Calibration::startAccelerometerCalibration); } else if (m_type == CAL_GYROSCOPE) { m_sensor = m_joystick->getActiveSetJoystick()->getSensor(GYROSCOPE); m_ui->steps->setText(tr("Gyroscope calibration corrects the sensor offset. " "This prevents cursor movement while the controller is at rest.")); connect(m_ui->startBtn, &QPushButton::clicked, this, &Calibration::startGyroscopeCalibration); } m_ui->statusStack->setCurrentIndex(0); m_calibrated = m_sensor->isCalibrated(); if (m_calibrated) { double offsetX, offsetY, offsetZ; m_sensor->getCalibration(&offsetX, &offsetY, &offsetZ); showSensorCalibrationValues(true, offsetX, true, offsetY, true, offsetZ); } else { showSensorCalibrationValues(false, 0.0, false, 0.0, false, 0.0); } m_ui->xAxisLabel->setVisible(true); m_ui->yAxisLabel->setVisible(true); m_ui->zAxisLabel->setVisible(true); m_ui->offsetXLabel->setVisible(true); m_ui->offsetYLabel->setVisible(true); m_ui->offsetZLabel->setVisible(true); m_ui->offsetXValue->setVisible(true); m_ui->offsetYValue->setVisible(true); m_ui->offsetZValue->setVisible(true); m_ui->resetBtn->setEnabled(m_calibrated); m_ui->saveBtn->setEnabled(false); m_ui->sensorStatusBoxWidget->setFocus(); m_ui->sensorStatusBoxWidget->setSensor(m_sensor); m_ui->sensorStatusBoxWidget->update(); m_ui->startBtn->setEnabled(true); m_ui->resetBtn->setEnabled(true); } } /** * @brief Performs linear regression on the measurement values of one axis to * determine offset and gain. * @param[out] offset The calculated offset. * @param[out] gain The calculated gain. * @param[in] xoffset The measured X value at the point (x, 0) * @param[in] xmin The measured X value at the point (x, AXISMIN) * @param[in] xmax The measured X value at the point (x, AXISMAX) * * Since the sum (AXISMIN + 0 + AXISMAX) is 0, the calculation below could * be simplified. */ void Calibration::stickRegression(double *offset, double *gain, double xoffset, double xmin, double xmax) { double ymin = GlobalVariables::JoyAxis::AXISMIN; double ymax = GlobalVariables::JoyAxis::AXISMAX; double sum_X = xoffset + xmin + xmax; double sum_X2 = xoffset * xoffset + xmin * xmin + xmax * xmax; double sum_XY = xmin * ymin + xmax * ymax; *offset = (-sum_X * sum_XY) / (3 * sum_X2 - sum_X * sum_X); *gain = 3 * sum_XY / (3 * sum_X2 - sum_X * sum_X); } /** * @brief Resets calibration values of the currently selected device and * updates UI. */ void Calibration::resetCalibrationValues() { if (m_type == CAL_STICK && m_stick != nullptr) { m_stick->resetCalibration(); showStickCalibrationValues(false, 0, false, 0, false, 0, false, 0); } else if ((m_type == CAL_ACCELEROMETER || m_type == CAL_GYROSCOPE) && m_sensor != nullptr) { m_sensor->resetCalibration(); showSensorCalibrationValues(false, 0, false, 0, false, 0); } m_calibrated = false; m_ui->saveBtn->setEnabled(false); m_ui->resetBtn->setEnabled(false); m_ui->stickStatusBoxWidget->update(); update(); } /** * @brief Asks the user for confirmation with a given message if the given * condition is false. * @param[in] message The message to show. * @param[in] confirmed True, if the action is already confirmed or no confirmation is necessary. * @returns True, if the action was confirmed. False otherwise. */ bool Calibration::askConfirmation(QString message, bool confirmed) { if (!confirmed) { QMessageBox msgBox; msgBox.setText(message); msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); switch (msgBox.exec()) { case QMessageBox::Ok: return true; case QMessageBox::Cancel: return false; default: return true; } } return true; } /** * @brief Device change event handler. Asks for confirmation if there are unsaved changes. */ void Calibration::deviceSelectionChanged(int index) { if (askConfirmation(tr("Calibration was not saved for the preset. Do you really want to continue?"), !m_changed)) { int data = m_ui->deviceComboBox->itemData(index).toInt(); selectTypeIndex(data); } else { int index = m_ui->deviceComboBox->findData(QVariant(m_type | (m_index << CAL_INDEX_POS))); m_ui->deviceComboBox->blockSignals(true); m_ui->deviceComboBox->setCurrentIndex(index); m_ui->deviceComboBox->blockSignals(false); } } /** * @brief Sensor data event handler. * Performs gyroscope offset and accelerometer neutral orientation estimation * and stops itself if the value was found or the process timed out. * * The gyroscope is only offset calibrated since gain calibration would require * an accurate turntable to apply a known rotation rate on all axes. * The offset is determined by calculating the mean output value at rest. * * The accelerometer calibration only rotates the coordinate system to the desired neutral * orientation. Calibrating offset and gain would require an accurate fixture * to align all axes parallel to gravity. * The neutral angles are determined by calculating the mean output value at the desired position. */ void Calibration::onSensorOffsetData(float x, float y, float z) { m_offset[0].process(x); m_offset[1].process(y); m_offset[2].process(z); bool xvalid = m_offset[0].calculateRelativeErrorSq() < CAL_ACCURACY_SQ && m_offset[0].getCount() > CAL_MIN_SAMPLES; bool yvalid = m_offset[1].calculateRelativeErrorSq() < CAL_ACCURACY_SQ && m_offset[1].getCount() > CAL_MIN_SAMPLES; bool zvalid = m_offset[2].calculateRelativeErrorSq() < CAL_ACCURACY_SQ && m_offset[2].getCount() > CAL_MIN_SAMPLES; showSensorCalibrationValues(xvalid, m_offset[0].getMean(), yvalid, m_offset[1].getMean(), zvalid, m_offset[2].getMean()); // Abort when end time is reached to avoid infinite loop // in case of noisy sensors. if ((xvalid && yvalid && zvalid) || (QDateTime::currentDateTime() > m_end_time)) { m_changed = true; disconnect(m_sensor, &JoySensor::moved, this, &Calibration::onSensorOffsetData); disconnect(m_ui->startBtn, &QPushButton::clicked, this, nullptr); if (m_type == CAL_ACCELEROMETER) connect(m_ui->startBtn, &QPushButton::clicked, this, &Calibration::startAccelerometerCalibration); else if (m_type == CAL_GYROSCOPE) connect(m_ui->startBtn, &QPushButton::clicked, this, &Calibration::startGyroscopeCalibration); m_ui->steps->setText(tr("Calibration completed.")); m_ui->startBtn->setText(tr("Start calibration")); m_ui->startBtn->setEnabled(true); m_ui->saveBtn->setEnabled(true); m_ui->deviceComboBox->setEnabled(true); update(); } } /** * @brief Stick data event handler. Performs stick offset estimation * and stops itself if the value was found or the process timed out. * * At the beginning, it waits for the first stick moved event and calculates * the event rate for the denoise lag filter. * Then it looks for local minima and maxima within the sticks dead zone * which are used to estimate the sticks center position. */ void Calibration::onStickOffsetData(int x, int y) { if (m_phase == 0) { m_rate_timer.start(); m_sample_count = 0; m_phase = 1; } else if (m_phase == 1) { if (++m_sample_count == STICK_RATE_SAMPLES) { int delta_t = m_rate_timer.elapsed(); m_rate_timer.invalidate(); m_filter[0] = PT1Filter(STICK_CAL_TAU, STICK_RATE_SAMPLES * 1000.0 / delta_t); m_filter[1] = PT1Filter(STICK_CAL_TAU, STICK_RATE_SAMPLES * 1000.0 / delta_t); m_sample_count = 0; m_end_time = QDateTime::currentDateTime().addSecs(CAL_TIMEOUT); m_phase = 2; } } else if (m_phase == 2) { double slopex = m_filter[0].getValue() - m_filter[0].process(x); double slopey = m_filter[1].getValue() - m_filter[1].process(y); if (((m_last_slope[0] < 0 && slopex > 0) || (m_last_slope[0] > 0 && slopex < 0)) && abs(x) < m_stick->getDeadZone()) { m_offset[0].process(x); } if (((m_last_slope[1] < 0 && slopey > 0) || (m_last_slope[1] > 0 && slopey < 0)) && abs(y) < m_stick->getDeadZone()) { m_offset[1].process(y); } // There are two move events generated for every hardware event, // one updates the X the other the Y value. This causes every second // derivate value to be zero. Ignore those values to get the real derivative. if (slopex != 0) m_last_slope[0] = slopex; if (slopey != 0) m_last_slope[1] = slopey; bool xvalid = m_offset[0].calculateRelativeErrorSq() < CAL_ACCURACY_SQ && m_offset[0].getCount() > CAL_MIN_SAMPLES; bool yvalid = m_offset[1].calculateRelativeErrorSq() < CAL_ACCURACY_SQ && m_offset[1].getCount() > CAL_MIN_SAMPLES; showStickCalibrationValues(xvalid, m_offset[0].getMean(), false, 1, yvalid, m_offset[1].getMean(), false, 1); if ((xvalid && yvalid) || QDateTime::currentDateTime() > m_end_time) m_phase = 3; } else if (m_phase == 3) { disconnect(m_stick, &JoyControlStick::moved, this, &Calibration::onStickOffsetData); m_ui->steps->setText( tr("Offset calibration completed. Click \"Continue calibration\" to continue with gain calibration.")); m_ui->startBtn->setEnabled(true); update(); } } /** * @brief Stick data event handler. Performs stick gain estimation * and stops itself if the value was found or the process timed out. * * It looks for local minima and maxima outside the sticks dead zone * which are used to estimate the sticks minimum and maximum position. */ void Calibration::onStickGainData(int x, int y) { double slopex = m_filter[0].getValue() - m_filter[0].process(x); double slopey = m_filter[1].getValue() - m_filter[1].process(y); if (m_last_slope[0] > 0 && slopex < 0 && m_filter[0].getValue() < -m_stick->getDeadZone()) { m_min[0].process(m_filter[0].getValue()); } else if (m_last_slope[0] < 0 && slopex > 0 && m_filter[0].getValue() > m_stick->getDeadZone()) { m_max[0].process(m_filter[0].getValue()); } if (m_last_slope[1] > 0 && slopey < 0 && m_filter[1].getValue() < -m_stick->getDeadZone()) { m_min[1].process(m_filter[1].getValue()); } else if (m_last_slope[1] < 0 && slopey > 0 && m_filter[1].getValue() > m_stick->getDeadZone()) { m_max[1].process(m_filter[1].getValue()); } // There are two move events generated for every hardware event, // one updates the X the other the Y value. This causes every second // derivate value to be zero. Ignore those values to get the real derivative. if (slopex != 0) m_last_slope[0] = slopex; if (slopey != 0) m_last_slope[1] = slopey; bool xvalid = m_min[0].calculateRelativeErrorSq() < CAL_ACCURACY_SQ && m_min[0].getCount() > CAL_MIN_SAMPLES && m_max[0].calculateRelativeErrorSq() < CAL_ACCURACY_SQ && m_max[0].getCount() > CAL_MIN_SAMPLES; bool yvalid = m_min[1].calculateRelativeErrorSq() < CAL_ACCURACY_SQ && m_min[1].getCount() > CAL_MIN_SAMPLES && m_max[1].calculateRelativeErrorSq() < CAL_ACCURACY_SQ && m_max[1].getCount() > CAL_MIN_SAMPLES; double offsetX, gainX, offsetY, gainY; stickRegression(&offsetX, &gainX, m_offset[0].getMean(), m_min[0].getMean(), m_max[0].getMean()); stickRegression(&offsetY, &gainY, m_offset[1].getMean(), m_min[1].getMean(), m_max[1].getMean()); showStickCalibrationValues(true, offsetX, xvalid, gainX, true, offsetY, yvalid, gainY); if ((xvalid && yvalid) || QDateTime::currentDateTime() > m_end_time) { m_changed = true; disconnect(m_stick, &JoyControlStick::moved, this, &Calibration::onStickGainData); disconnect(m_ui->startBtn, &QPushButton::clicked, this, nullptr); connect(m_ui->startBtn, &QPushButton::clicked, this, &Calibration::startStickOffsetCalibration); m_ui->steps->setText("Calibration completed."); m_ui->startBtn->setText(tr("Start calibration")); m_ui->startBtn->setEnabled(true); m_ui->saveBtn->setEnabled(true); m_ui->deviceComboBox->setEnabled(true); update(); } } /** * @brief Save calibration values into the device object. */ void Calibration::saveSettings() { if (m_type == CAL_STICK) { double offsetX, gainX, offsetY, gainY; stickRegression(&offsetX, &gainX, m_offset[0].getMean(), m_min[0].getMean(), m_max[0].getMean()); stickRegression(&offsetY, &gainY, m_offset[1].getMean(), m_min[1].getMean(), m_max[1].getMean()); m_joystick->updateStickCalibration(m_index, offsetX, gainX, offsetY, gainY); showStickCalibrationValues(true, offsetX, true, gainX, true, offsetY, true, gainY); } else if (m_type == CAL_ACCELEROMETER) { m_joystick->updateAccelerometerCalibration(m_offset[0].getMean(), m_offset[1].getMean(), m_offset[2].getMean()); } else if (m_type == CAL_GYROSCOPE) { m_joystick->updateGyroscopeCalibration(m_offset[0].getMean(), m_offset[1].getMean(), m_offset[2].getMean()); } m_changed = false; m_calibrated = true; m_ui->saveBtn->setEnabled(false); m_ui->resetBtn->setEnabled(true); } /** * @brief Shows user instructions for accelerometer calibration and initializes estimators. */ void Calibration::startAccelerometerCalibration() { if (m_sensor == nullptr) return; if (askConfirmation(tr("Calibration was saved for the preset. Do you really want to reset settings?"), !m_calibrated)) { m_offset[0].reset(); m_offset[1].reset(); m_offset[2].reset(); m_sensor->resetCalibration(); m_calibrated = false; m_ui->steps->setText(tr("Hold the controller in the desired neutral position and press continue.")); setWindowTitle(tr("Calibrating accelerometer")); m_ui->startBtn->setText(tr("Continue calibration")); update(); m_ui->resetBtn->setEnabled(false); m_ui->deviceComboBox->setEnabled(false); disconnect(m_ui->startBtn, &QPushButton::clicked, this, nullptr); connect(m_ui->startBtn, &QPushButton::clicked, this, &Calibration::startAccelerometerAngleCalibration); } } /** * @brief Show calibration message to the user and enable accelerometer data event handler. */ void Calibration::startAccelerometerAngleCalibration() { if (m_sensor != nullptr) { m_end_time = QDateTime::currentDateTime().addSecs(CAL_TIMEOUT); m_ui->steps->setText( tr("Collecting accelerometer data...\nPlease hold the controller still.\nThis can take up to %1 seconds.") .arg(CAL_TIMEOUT)); connect(m_sensor, &JoySensor::moved, this, &Calibration::onSensorOffsetData); update(); m_ui->startBtn->setEnabled(false); disconnect(m_ui->startBtn, &QPushButton::clicked, this, nullptr); } } /** * @brief Shows user instructions for gyroscope calibration and initializes estimators. */ void Calibration::startGyroscopeCalibration() { if (m_sensor == nullptr) return; if (askConfirmation(tr("Calibration was saved for the preset. Do you really want to reset settings?"), !m_calibrated)) { m_offset[0].reset(); m_offset[1].reset(); m_offset[2].reset(); m_sensor->resetCalibration(); m_calibrated = false; m_ui->steps->setText(tr("Place the controller at rest, e.g. put it on the desk, " "and press continue.")); setWindowTitle(tr("Calibrating gyroscope")); m_ui->startBtn->setText(tr("Continue calibration")); update(); m_ui->resetBtn->setEnabled(false); m_ui->deviceComboBox->setEnabled(false); disconnect(m_ui->startBtn, &QPushButton::clicked, this, nullptr); connect(m_ui->startBtn, &QPushButton::clicked, this, &Calibration::startGyroscopeOffsetCalibration); } } /** * @brief Show calibration message to the user and enable gyroscope data event handler. */ void Calibration::startGyroscopeOffsetCalibration() { if (m_sensor != nullptr) { m_end_time = QDateTime::currentDateTime().addSecs(CAL_TIMEOUT); m_ui->steps->setText(tr("Collecting gyroscope data...\nThis can take up to %1 seconds.").arg(CAL_TIMEOUT)); connect(m_sensor, &JoySensor::moved, this, &Calibration::onSensorOffsetData); update(); m_ui->startBtn->setEnabled(false); disconnect(m_ui->startBtn, &QPushButton::clicked, this, nullptr); } } /** * @brief Shows user instructions for stick offset calibration, initializes estimators * and connects stick data event handlers. */ void Calibration::startStickOffsetCalibration() { if (m_stick == nullptr) return; if (askConfirmation(tr("Calibration was saved for the preset. Do you really want to reset settings?"), !m_calibrated)) { m_offset[0].reset(); m_offset[1].reset(); m_last_slope[0] = 0; m_last_slope[1] = 0; m_stick->resetCalibration(); m_calibrated = false; m_phase = 0; m_ui->steps->setText( tr("Now move the stick several times to the maximum in different direction and back to center.\n" "This can take up to %1 seconds.") .arg(CAL_TIMEOUT)); setWindowTitle(tr("Calibrating stick")); m_ui->startBtn->setText(tr("Continue calibration")); m_ui->startBtn->setEnabled(false); m_ui->resetBtn->setEnabled(false); m_ui->deviceComboBox->setEnabled(false); disconnect(m_ui->startBtn, &QPushButton::clicked, this, nullptr); connect(m_ui->startBtn, &QPushButton::clicked, this, &Calibration::startStickGainCalibration); connect(m_stick, &JoyControlStick::moved, this, &Calibration::onStickOffsetData); update(); } } /** * @brief Shows user instructions for stick gain calibration, initializes estimators * and connects stick data event handlers. */ void Calibration::startStickGainCalibration() { if (m_stick == nullptr) return; m_min[0].reset(); m_min[1].reset(); m_max[0].reset(); m_max[1].reset(); m_filter[0].reset(); m_filter[1].reset(); m_ui->steps->setText(tr("Now move the stick in full circles for several times.\n" "This can take up to %1 seconds.") .arg(CAL_TIMEOUT)); m_ui->startBtn->setEnabled(false); update(); disconnect(m_ui->startBtn, &QPushButton::clicked, this, nullptr); connect(m_ui->startBtn, &QPushButton::clicked, this, &Calibration::startStickOffsetCalibration); connect(m_stick, &JoyControlStick::moved, this, &Calibration::onStickGainData); m_end_time = QDateTime::currentDateTime().addSecs(CAL_TIMEOUT); } AntiMicroX-antimicrox-b300273/src/gui/calibration.h000066400000000000000000000067121471077622000221730ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "pt1filter.h" #include "statisticsestimator.h" #include #include #include class JoyControlStick; class JoySensor; class InputDevice; namespace Ui { class Calibration; } /** * @brief Opens calibration window used for calibration * * @details Class used for calibration of joysticks, gyroscopes etc. */ class Calibration : public QDialog { Q_OBJECT public: enum CalibrationType { CAL_NONE, CAL_STICK, CAL_ACCELEROMETER, CAL_GYROSCOPE, CAL_TYPE_MASK = 0x0000FFFF, CAL_INDEX_MASK = 0xFFFF0000, CAL_INDEX_POS = 16 }; explicit Calibration(InputDevice *joystick, QDialog *parent = 0); ~Calibration(); protected: void resetCalibrationValues(); bool askConfirmation(QString message, bool confirmed); void showSensorCalibrationValues(bool offsetXvalid, double offsetX, bool offsetYvalid, double offsetY, bool offsetZvalid, double offsetZ); void showStickCalibrationValues(bool offsetXvalid, double offsetX, bool gainXvalid, double gainX, bool offsetYvalid, double offsetY, bool gainYvalid, double gainY); void hideCalibrationData(); void selectTypeIndex(unsigned int type_index); static void stickRegression(double *offset, double *gain, double xoffset, double xmin, double xmax); private: Ui::Calibration *m_ui; CalibrationType m_type; unsigned int m_index; bool m_calibrated; bool m_changed; JoyControlStick *m_stick; JoySensor *m_sensor; InputDevice *m_joystick; StatisticsEstimator m_offset[3]; StatisticsEstimator m_min[2]; StatisticsEstimator m_max[2]; PT1Filter m_filter[2]; double m_last_slope[2]; QDateTime m_end_time; QElapsedTimer m_rate_timer; int m_sample_count; int m_phase; static const int CAL_MIN_SAMPLES; static const double CAL_ACCURACY_SQ; static const double STICK_CAL_TAU; static const int STICK_RATE_SAMPLES; static const int CAL_TIMEOUT; public slots: void saveSettings(); void startAccelerometerCalibration(); void startAccelerometerAngleCalibration(); void startGyroscopeCalibration(); void startGyroscopeOffsetCalibration(); void startStickOffsetCalibration(); void startStickGainCalibration(); protected slots: void closeEvent(QCloseEvent *event) override; void resetSettings(); void deviceSelectionChanged(int index); void onSensorOffsetData(float x, float y, float z); void onStickOffsetData(int x, int y); void onStickGainData(int x, int y); signals: void propertyUpdated(); }; AntiMicroX-antimicrox-b300273/src/gui/calibration.ui000066400000000000000000000204261471077622000223570ustar00rootroot00000000000000 Calibration 0 0 800 600 700 600 Form 0 0 300 300 16777215 16777215 0 0 200 200 1 Input to calibrate: Qt::Vertical 20 40 Steps Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true Z TextLabel X TextLabel gain TextLabel offset Y offset offset TextLabel gain TextLabel gain TextLabel Qt::Vertical 20 40 false Reset settings false Start calibration Qt::Horizontal 40 20 false Save Close JoySensorStatusBox QWidget
joysensorstatusbox.h
JoyControlStickStatusBox QWidget
joycontrolstickstatusbox.h
AntiMicroX-antimicrox-b300273/src/gui/capturedwindowinfodialog.cpp000066400000000000000000000117611471077622000253320ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "capturedwindowinfodialog.h" #include "ui_capturedwindowinfodialog.h" #include #include #include #ifdef Q_OS_WIN #include "winextras.h" #else #include "x11extras.h" #endif #ifdef Q_OS_WIN CapturedWindowInfoDialog::CapturedWindowInfoDialog(QWidget *parent) #else CapturedWindowInfoDialog::CapturedWindowInfoDialog(long window, QWidget *parent) #endif : QDialog(parent) , ui(new Ui::CapturedWindowInfoDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); selectedMatch = WindowNone; #ifdef Q_OS_UNIX X11Extras *info = X11Extras::getInstance(); ui->winPathChoiceComboBox->setVisible(false); #endif bool setRadioDefault = false; fullWinPath = false; #ifdef Q_OS_WIN ui->winClassCheckBox->setVisible(false); ui->winClassLabel->setVisible(false); ui->winClassHeadLabel->setVisible(false); #else winClass = info->getWindowClass(static_cast(window)); ui->winClassLabel->setText(winClass); if (winClass.isEmpty()) { ui->winClassCheckBox->setEnabled(false); ui->winClassCheckBox->setChecked(false); } else { ui->winClassCheckBox->setChecked(true); setRadioDefault = true; } ui->winPathChoiceComboBox->setVisible(false); #endif #ifdef Q_OS_WIN winName = WinExtras::getCurrentWindowText(); #else winName = info->getWindowTitle(window); #endif ui->winTitleLabel->setText(winName); if (winName.isEmpty()) { ui->winTitleCheckBox->setEnabled(false); ui->winTitleCheckBox->setChecked(false); } else if (!setRadioDefault) { ui->winTitleCheckBox->setChecked(true); setRadioDefault = true; } ui->winPathLabel->clear(); #ifdef Q_OS_WIN winPath = WinExtras::getForegroundWindowExePath(); ui->winPathLabel->setText(winPath); if (winPath.isEmpty()) { ui->winPathCheckBox->setEnabled(false); ui->winPathCheckBox->setChecked(false); } else { ui->winPathCheckBox->setChecked(true); ui->winTitleCheckBox->setChecked(false); setRadioDefault = true; } #elif defined(Q_OS_LINUX) int pid = info->getApplicationPid(static_cast(window)); if (pid > 0) { QString exepath = X11Extras::getInstance()->getApplicationLocation(pid); if (!exepath.isEmpty()) { ui->winPathLabel->setText(exepath); winPath = exepath; if (!setRadioDefault) ui->winTitleCheckBox->setChecked(true); } else { ui->winPathCheckBox->setEnabled(false); ui->winPathCheckBox->setChecked(false); } } else { ui->winPathCheckBox->setEnabled(false); ui->winPathCheckBox->setChecked(false); } #endif if (winClass.isEmpty() && winName.isEmpty() && winPath.isEmpty()) { QPushButton *button = ui->buttonBox->button(QDialogButtonBox::Ok); button->setEnabled(false); } connect(this, &CapturedWindowInfoDialog::accepted, this, &CapturedWindowInfoDialog::populateOption); } CapturedWindowInfoDialog::~CapturedWindowInfoDialog() { delete ui; } void CapturedWindowInfoDialog::populateOption() { if (ui->winClassCheckBox->isChecked()) selectedMatch = selectedMatch | WindowClass; if (ui->winTitleCheckBox->isChecked()) selectedMatch = selectedMatch | WindowName; if (ui->winPathCheckBox->isChecked()) { selectedMatch = selectedMatch | WindowPath; if (ui->winPathChoiceComboBox->currentIndex() == 0) fullWinPath = true; else fullWinPath = false; } } CapturedWindowInfoDialog::CapturedWindowOption CapturedWindowInfoDialog::getSelectedOptions() { return selectedMatch; } QString CapturedWindowInfoDialog::getWindowClass() { return winClass; } QString CapturedWindowInfoDialog::getWindowName() { return winName; } QString CapturedWindowInfoDialog::getWindowPath() { return winPath; } bool CapturedWindowInfoDialog::useFullWindowPath() { return fullWinPath; } AntiMicroX-antimicrox-b300273/src/gui/capturedwindowinfodialog.h000066400000000000000000000036001471077622000247700ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef UNIXWINDOWINFODIALOG_H #define UNIXWINDOWINFODIALOG_H #include class QWidget; namespace Ui { class CapturedWindowInfoDialog; } class CapturedWindowInfoDialog : public QDialog { Q_OBJECT public: #ifdef Q_OS_WIN explicit CapturedWindowInfoDialog(QWidget *parent = 0); #else explicit CapturedWindowInfoDialog(long window, QWidget *parent = nullptr); #endif ~CapturedWindowInfoDialog(); enum { WindowNone = 0, WindowClass = (1 << 0), WindowName = (1 << 1), WindowPath = (1 << 2), }; typedef int CapturedWindowOption; QString getWindowClass(); QString getWindowName(); QString getWindowPath(); bool useFullWindowPath(); CapturedWindowOption getSelectedOptions(); private: Ui::CapturedWindowInfoDialog *ui; CapturedWindowOption selectedMatch; QString winClass; QString winName; QString winPath; bool fullWinPath; private slots: void populateOption(); }; #endif // UNIXWINDOWINFODIALOG_H AntiMicroX-antimicrox-b300273/src/gui/capturedwindowinfodialog.ui000066400000000000000000000137721471077622000251710ustar00rootroot00000000000000 CapturedWindowInfoDialog 0 0 533 363 Captured Window Properties 20 50 false Information About Window true 20 Class: true TextLabel Title: true TextLabel Path: true TextLabel Match By Properties true false false Class Title Path true Full Path File Name Qt::Vertical 20 40 Qt::Horizontal Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() CapturedWindowInfoDialog accept() 248 254 157 274 buttonBox rejected() CapturedWindowInfoDialog reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/dpadeditdialog.cpp000066400000000000000000000537341471077622000232030ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "dpadeditdialog.h" #include "ui_dpadeditdialog.h" #include "antkeymapper.h" #include "common.h" #include "event.h" #include "inputdevice.h" #include "joydpad.h" #include "mousedialog/mousedpadsettingsdialog.h" #include "setjoystick.h" #include #include #include DPadEditDialog::DPadEditDialog(JoyDPad *dpad, QWidget *parent) : QDialog(parent, Qt::Window) , ui(new Ui::DPadEditDialog) , helper(dpad) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); this->dpad = dpad; getHelperLocal().moveToThread(dpad->thread()); PadderCommon::inputDaemonMutex.lock(); updateWindowTitleDPadName(); switch (dpad->getJoyMode()) { case JoyDPad::StandardMode: ui->joyModeComboBox->setCurrentIndex(0); break; case JoyDPad::EightWayMode: ui->joyModeComboBox->setCurrentIndex(1); break; case JoyDPad::FourWayCardinal: ui->joyModeComboBox->setCurrentIndex(2); break; case JoyDPad::FourWayDiagonal: ui->joyModeComboBox->setCurrentIndex(3); break; } selectCurrentPreset(); ui->dpadNameLineEdit->setText(dpad->getDpadName()); int dpadDelay = dpad->getDPadDelay(); ui->dpadDelaySlider->setValue(dpadDelay * .1); ui->dpadDelayDoubleSpinBox->setValue(dpadDelay * .001); PadderCommon::inputDaemonMutex.unlock(); connect(ui->presetsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &DPadEditDialog::implementPresets); connect(ui->joyModeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &DPadEditDialog::implementModes); connect(ui->mouseSettingsPushButton, &QPushButton::clicked, this, &DPadEditDialog::openMouseSettingsDialog); connect(ui->dpadNameLineEdit, &QLineEdit::textEdited, dpad, &JoyDPad::setDPadName); connect(ui->dpadDelaySlider, static_cast(&QSlider::valueChanged), &helper, &DPadEditDialogHelper::updateJoyDPadDelay); connect(dpad, &JoyDPad::dpadDelayChanged, this, &DPadEditDialog::updateDPadDelaySpinBox); connect(ui->dpadDelayDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &DPadEditDialog::updateDPadDelaySlider); connect(dpad, &JoyDPad::dpadNameChanged, this, &DPadEditDialog::updateWindowTitleDPadName); } DPadEditDialog::~DPadEditDialog() { delete ui; } void DPadEditDialog::implementPresets(int index) { JoyButtonSlot *upButtonSlot = nullptr; JoyButtonSlot *downButtonSlot = nullptr; JoyButtonSlot *leftButtonSlot = nullptr; JoyButtonSlot *rightButtonSlot = nullptr; JoyButtonSlot *upLeftButtonSlot = nullptr; JoyButtonSlot *upRightButtonSlot = nullptr; JoyButtonSlot *downLeftButtonSlot = nullptr; JoyButtonSlot *downRightButtonSlot = nullptr; switch (index) { case 1: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); break; case 2: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); break; case 3: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); break; case 4: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); break; case 5: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up), Qt::Key_Up, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down), Qt::Key_Down, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left), Qt::Key_Left, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right), Qt::Key_Right, JoyButtonSlot::JoyKeyboard, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); break; case 6: PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W), Qt::Key_W, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S), Qt::Key_S, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A), Qt::Key_A, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D), Qt::Key_D, JoyButtonSlot::JoyKeyboard, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); break; case 7: PadderCommon::inputDaemonMutex.lock(); if ((ui->joyModeComboBox->currentIndex() == 0) || (ui->joyModeComboBox->currentIndex() == 2)) { upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); } else if (ui->joyModeComboBox->currentIndex() == 1) { upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); } else if (ui->joyModeComboBox->currentIndex() == 3) { upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); } PadderCommon::inputDaemonMutex.unlock(); break; case 0: case 8: QMetaObject::invokeMethod(&helper, "clearButtonsSlotsEventReset", Qt::BlockingQueuedConnection); dpad->getJoyButton(JoyDPadButton::DpadUp)->buildActiveZoneSummaryString(); dpad->getJoyButton(JoyDPadButton::DpadDown)->buildActiveZoneSummaryString(); dpad->getJoyButton(JoyDPadButton::DpadLeft)->buildActiveZoneSummaryString(); dpad->getJoyButton(JoyDPadButton::DpadRight)->buildActiveZoneSummaryString(); break; } QHash tempHash; tempHash.insert(JoyDPadButton::DpadUp, upButtonSlot); tempHash.insert(JoyDPadButton::DpadDown, downButtonSlot); tempHash.insert(JoyDPadButton::DpadLeft, leftButtonSlot); tempHash.insert(JoyDPadButton::DpadRight, rightButtonSlot); tempHash.insert(JoyDPadButton::DpadLeftUp, upLeftButtonSlot); tempHash.insert(JoyDPadButton::DpadRightUp, upRightButtonSlot); tempHash.insert(JoyDPadButton::DpadLeftDown, downLeftButtonSlot); tempHash.insert(JoyDPadButton::DpadRightDown, downRightButtonSlot); getHelperLocal().setPendingSlots(&tempHash); QMetaObject::invokeMethod(&helper, "setFromPendingSlots", Qt::BlockingQueuedConnection); } void DPadEditDialog::implementModes(int index) { PadderCommon::inputDaemonMutex.lock(); dpad->releaseButtonEvents(); switch (index) { case 0: dpad->setJoyMode(JoyDPad::StandardMode); break; case 1: dpad->setJoyMode(JoyDPad::EightWayMode); break; case 2: dpad->setJoyMode(JoyDPad::FourWayCardinal); break; case 3: dpad->setJoyMode(JoyDPad::FourWayDiagonal); break; } PadderCommon::inputDaemonMutex.unlock(); } void DPadEditDialog::selectCurrentPreset() { JoyDPadButton *upButton = dpad->getJoyButton(JoyDPadButton::DpadUp); QList *upslots = upButton->getAssignedSlots(); JoyDPadButton *downButton = dpad->getJoyButton(JoyDPadButton::DpadDown); QList *downslots = downButton->getAssignedSlots(); JoyDPadButton *leftButton = dpad->getJoyButton(JoyDPadButton::DpadLeft); QList *leftslots = leftButton->getAssignedSlots(); JoyDPadButton *rightButton = dpad->getJoyButton(JoyDPadButton::DpadRight); QList *rightslots = rightButton->getAssignedSlots(); if ((upslots->length() == 1) && (downslots->length() == 1) && (leftslots->length() == 1) && (rightslots->length() == 1)) { JoyButtonSlot *upslot = upslots->at(0); JoyButtonSlot *downslot = downslots->at(0); JoyButtonSlot *leftslot = leftslots->at(0); JoyButtonSlot *rightslot = rightslots->at(0); if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseUp) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseDown) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseRight)) { ui->presetsComboBox->setCurrentIndex(1); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseUp) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseDown) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseRight) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { ui->presetsComboBox->setCurrentIndex(2); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseDown) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseUp) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseRight)) { ui->presetsComboBox->setCurrentIndex(3); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseDown) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseUp) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseRight) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { ui->presetsComboBox->setCurrentIndex(4); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right))) { ui->presetsComboBox->setCurrentIndex(5); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D))) { ui->presetsComboBox->setCurrentIndex(6); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6))) { ui->presetsComboBox->setCurrentIndex(7); } } else if ((upslots->length() == 0) && (downslots->length() == 0) && (leftslots->length() == 0) && (rightslots->length() == 0)) { ui->presetsComboBox->setCurrentIndex(8); } } void DPadEditDialog::openMouseSettingsDialog() { ui->mouseSettingsPushButton->setEnabled(false); MouseDPadSettingsDialog *dialog = new MouseDPadSettingsDialog(this->dpad, this); dialog->show(); connect(this, &DPadEditDialog::finished, dialog, &MouseDPadSettingsDialog::close); connect(dialog, &MouseDPadSettingsDialog::finished, this, &DPadEditDialog::enableMouseSettingButton); } void DPadEditDialog::enableMouseSettingButton() { ui->mouseSettingsPushButton->setEnabled(true); } /** * @brief Update QDoubleSpinBox value based on updated dpad delay value. * @param Delay value obtained from JoyDPad. */ void DPadEditDialog::updateDPadDelaySpinBox(int value) { double temp = value * 0.001; ui->dpadDelayDoubleSpinBox->setValue(temp); } /** * @brief Update QSlider value based on value from QDoubleSpinBox. * @param Value from QDoubleSpinBox. */ void DPadEditDialog::updateDPadDelaySlider(double value) { int currentDpadDelay = value * 100; if (ui->dpadDelaySlider->value() != currentDpadDelay) { ui->dpadDelaySlider->setValue(currentDpadDelay); } } void DPadEditDialog::updateWindowTitleDPadName() { QString temp = QString(tr("Set")).append(" "); if (!dpad->getDpadName().isEmpty()) temp.append(dpad->getName(false, true)); else temp.append(dpad->getName()); if (dpad->getParentSet()->getIndex() != 0) { int setIndex = dpad->getParentSet()->getRealIndex(); temp.append(" [").append(tr("Set %1").arg(setIndex)); QString setName = dpad->getParentSet()->getName(); if (!setName.isEmpty()) { temp.append(": ").append(setName); } temp.append("]"); } setWindowTitle(temp); } JoyDPad *DPadEditDialog::getDPad() const { return dpad; } DPadEditDialogHelper const &DPadEditDialog::getHelper() { return helper; } DPadEditDialogHelper &DPadEditDialog::getHelperLocal() { return helper; } AntiMicroX-antimicrox-b300273/src/gui/dpadeditdialog.h000066400000000000000000000033241471077622000226360ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DPADEDITDIALOG_H #define DPADEDITDIALOG_H #include "uihelpers/dpadeditdialoghelper.h" #include class JoyDPad; class QWidget; namespace Ui { class DPadEditDialog; } class DPadEditDialog : public QDialog { Q_OBJECT public: explicit DPadEditDialog(JoyDPad *dpad, QWidget *parent = nullptr); ~DPadEditDialog(); JoyDPad *getDPad() const; DPadEditDialogHelper const &getHelper(); protected: void selectCurrentPreset(); private slots: void implementPresets(int index); void implementModes(int index); void openMouseSettingsDialog(); void enableMouseSettingButton(); void updateWindowTitleDPadName(); void updateDPadDelaySpinBox(int value); void updateDPadDelaySlider(double value); private: Ui::DPadEditDialog *ui; DPadEditDialogHelper &getHelperLocal(); JoyDPad *dpad; DPadEditDialogHelper helper; }; #endif // DPADEDITDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/dpadeditdialog.ui000066400000000000000000000211351471077622000230240ustar00rootroot00000000000000 DPadEditDialog Qt::WindowModal 0 0 528 334 Dialog Presets: 282 0 Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Dpad Mode: 282 0 Standard: 8 region dpad with two direction buttons active when the dpad is in a diagonal region. Eight Way: 8 region dpad with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region dpad with regions corresponding to the cardinal directions of the dpad. Useful for menus. 4 Way Diagonal: 4 region dpad with each region corresponding to a diagonal zone. Standard Eight Way 4 Way Cardinal 4 Way Diagonal Qt::Vertical QSizePolicy::Fixed 20 20 DPad Delay: Time lapsed before a direction change is taken into effect. 0 100 1 10 0 0 Qt::Horizontal QSlider::TicksBelow 0 Time lapsed before a direction change is taken into effect. false s 2 1.000000000000000 0.010000000000000 Qt::Vertical QSizePolicy::MinimumExpanding 20 36 10 6 &Name: dpadNameLineEdit Specify the name of a dpad. Mouse Settings Qt::Horizontal Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() DPadEditDialog accept() 248 254 157 274 buttonBox rejected() DPadEditDialog reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/editalldefaultautoprofiledialog.cpp000066400000000000000000000065221471077622000266530ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "editalldefaultautoprofiledialog.h" #include "ui_editalldefaultautoprofiledialog.h" #include "antimicrosettings.h" #include "autoprofileinfo.h" #include "common.h" #include #include #include #include #include EditAllDefaultAutoProfileDialog::EditAllDefaultAutoProfileDialog(AutoProfileInfo *info, AntiMicroSettings *settings, QWidget *parent) : QDialog(parent) , ui(new Ui::EditAllDefaultAutoProfileDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); this->info = info; this->settings = settings; if (!info->getProfileLocation().isEmpty()) ui->profileLineEdit->setText(info->getProfileLocation()); connect(ui->profileBrowsePushButton, &QPushButton::clicked, this, &EditAllDefaultAutoProfileDialog::openProfileBrowseDialog); connect(this, &EditAllDefaultAutoProfileDialog::accepted, this, &EditAllDefaultAutoProfileDialog::saveAutoProfileInformation); } EditAllDefaultAutoProfileDialog::~EditAllDefaultAutoProfileDialog() { delete ui; } void EditAllDefaultAutoProfileDialog::openProfileBrowseDialog() { QString preferredProfileDir = PadderCommon::preferredProfileDir(settings); QString profileFilename = QFileDialog::getOpenFileName(this, tr("Open Config"), preferredProfileDir, QString("Config Files (*.amgp *.xml)")); if (!profileFilename.isNull() && !profileFilename.isEmpty()) ui->profileLineEdit->setText(profileFilename); } void EditAllDefaultAutoProfileDialog::saveAutoProfileInformation() { // info->setGUID("all"); info->setUniqueID("all"); info->setProfileLocation(ui->profileLineEdit->text()); info->setActive(true); } AutoProfileInfo *EditAllDefaultAutoProfileDialog::getAutoProfile() const { return info; } void EditAllDefaultAutoProfileDialog::accept() { bool validForm = true; QString errorString = QString(); if (ui->profileLineEdit->text().length() > 0) { QFileInfo profileInfo(ui->profileLineEdit->text()); if (!profileInfo.exists()) { validForm = false; errorString = tr("Profile file path is invalid."); } } if (validForm) { QDialog::accept(); } else { QMessageBox msgBox; msgBox.setText(errorString); msgBox.setStandardButtons(QMessageBox::Close); msgBox.exec(); } } AntiMicroSettings *EditAllDefaultAutoProfileDialog::getSettings() const { return settings; } AntiMicroX-antimicrox-b300273/src/gui/editalldefaultautoprofiledialog.h000066400000000000000000000032221471077622000263120ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef EDITALLDEFAULTAUTOPROFILEDIALOG_H #define EDITALLDEFAULTAUTOPROFILEDIALOG_H #include class AutoProfileInfo; class AntiMicroSettings; class QWidget; namespace Ui { class EditAllDefaultAutoProfileDialog; } class EditAllDefaultAutoProfileDialog : public QDialog { Q_OBJECT public: explicit EditAllDefaultAutoProfileDialog(AutoProfileInfo *info, AntiMicroSettings *settings, QWidget *parent = nullptr); ~EditAllDefaultAutoProfileDialog(); AutoProfileInfo *getAutoProfile() const; AntiMicroSettings *getSettings() const; protected: virtual void accept(); private: Ui::EditAllDefaultAutoProfileDialog *ui; AutoProfileInfo *info; AntiMicroSettings *settings; private slots: void openProfileBrowseDialog(); void saveAutoProfileInformation(); }; #endif // EDITALLDEFAULTAUTOPROFILEDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/editalldefaultautoprofiledialog.ui000066400000000000000000000047721471077622000265130ustar00rootroot00000000000000 EditAllDefaultAutoProfileDialog 0 0 384 114 Default Profile true Profile: profileLineEdit Browse Qt::Vertical QSizePolicy::Fixed 20 10 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() EditAllDefaultAutoProfileDialog accept() 248 254 157 274 buttonBox rejected() EditAllDefaultAutoProfileDialog reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/extraprofilesettingsdialog.cpp000066400000000000000000000044661471077622000257100ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "extraprofilesettingsdialog.h" #include "ui_extraprofilesettingsdialog.h" #include "inputdevice.h" #include ExtraProfileSettingsDialog::ExtraProfileSettingsDialog(InputDevice *device, QWidget *parent) : QDialog(parent) , ui(new Ui::ExtraProfileSettingsDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); this->device = device; ui->pressValueLabel->setText(QString::number(0.10, 'g', 3).append("").append(tr("s"))); if (device->getDeviceKeyPressTime() > 0) { int temppress = device->getDeviceKeyPressTime(); ui->keyPressHorizontalSlider->setValue(device->getDeviceKeyPressTime() / 10); ui->pressValueLabel->setText(QString::number(temppress / 1000.0, 'g', 3).append("").append(tr("s"))); } if (!device->getProfileName().isEmpty()) ui->profileNameLineEdit->setText(device->getProfileName()); connect(ui->keyPressHorizontalSlider, &QSlider::valueChanged, this, &ExtraProfileSettingsDialog::changeDeviceKeyPress); connect(ui->profileNameLineEdit, &QLineEdit::textChanged, device, &InputDevice::setProfileName); } ExtraProfileSettingsDialog::~ExtraProfileSettingsDialog() { delete ui; } void ExtraProfileSettingsDialog::changeDeviceKeyPress(int value) { int temppress = value * 10; device->setDeviceKeyPressTime(temppress); ui->pressValueLabel->setText(QString::number(temppress / 1000.0, 'g', 3).append("").append(tr("s"))); } InputDevice *ExtraProfileSettingsDialog::getDevice() const { return device; } AntiMicroX-antimicrox-b300273/src/gui/extraprofilesettingsdialog.h000066400000000000000000000025501471077622000253450ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KEYDELAYDIALOG_H #define KEYDELAYDIALOG_H #include class InputDevice; class QWidget; namespace Ui { class ExtraProfileSettingsDialog; } class ExtraProfileSettingsDialog : public QDialog { Q_OBJECT public: explicit ExtraProfileSettingsDialog(InputDevice *device, QWidget *parent = nullptr); ~ExtraProfileSettingsDialog(); InputDevice *getDevice() const; private: Ui::ExtraProfileSettingsDialog *ui; InputDevice *device; private slots: void changeDeviceKeyPress(int value); }; #endif // KEYDELAYDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/extraprofilesettingsdialog.ui000066400000000000000000000075421471077622000255410ustar00rootroot00000000000000 ExtraProfileSettingsDialog 0 0 439 144 396 136 Extra Profile Settings true 10 10 20 0 Key Press Time: 1 100 10 Qt::Horizontal 0.00 ms 36 Profile Name: 50 Qt::Vertical QSizePolicy::Fixed 20 10 Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() ExtraProfileSettingsDialog accept() 248 254 157 274 buttonBox rejected() ExtraProfileSettingsDialog reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/flashbuttonwidget.cpp000066400000000000000000000067521471077622000240000ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "flashbuttonwidget.h" #include #include #include #include #include #include FlashButtonWidget::FlashButtonWidget(QWidget *parent) : QPushButton(parent) { isflashing = false; m_displayNames = false; leftAlignText = false; } FlashButtonWidget::FlashButtonWidget(bool displayNames, QWidget *parent) : QPushButton(parent) { isflashing = false; m_displayNames = displayNames; leftAlignText = false; } void FlashButtonWidget::flash() { isflashing = true; this->style()->unpolish(this); this->style()->polish(this); } void FlashButtonWidget::unflash() { isflashing = false; this->style()->unpolish(this); this->style()->polish(this); } void FlashButtonWidget::refreshLabel() { QString new_label = generateLabel(); setText(new_label); qDebug() << "label has been set: " << new_label; } bool FlashButtonWidget::isButtonFlashing() { return isflashing; } void FlashButtonWidget::toggleNameDisplay() { m_displayNames = !m_displayNames; refreshLabel(); } void FlashButtonWidget::setDisplayNames(bool display) { m_displayNames = display; } bool FlashButtonWidget::isDisplayingNames() { return m_displayNames; } void FlashButtonWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); QFont tempScaledFont = painter.font(); QFont temp; tempScaledFont.setPointSize(temp.pointSize()); QFontMetrics fm(tempScaledFont); bool reduce = false; #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) while ((this->width() < fm.horizontalAdvance(text())) && (tempScaledFont.pointSize() >= 7)) #else while ((this->width() < fm.width(text())) && (tempScaledFont.pointSize() >= 7)) #endif { tempScaledFont.setPointSize(tempScaledFont.pointSize() - 1); painter.setFont(tempScaledFont); fm = painter.fontMetrics(); reduce = true; } bool changeFontSize = this->font().pointSize() != tempScaledFont.pointSize(); if (changeFontSize) { if (reduce && !leftAlignText) { leftAlignText = !leftAlignText; setStyleSheet("text-align: left;"); this->style()->unpolish(this); this->style()->polish(this); } else if (!reduce && leftAlignText) { leftAlignText = !leftAlignText; setStyleSheet("text-align: center;"); this->style()->unpolish(this); this->style()->polish(this); } this->setFont(tempScaledFont); } QPushButton::paintEvent(event); } void FlashButtonWidget::retranslateUi() { refreshLabel(); } bool FlashButtonWidget::ifDisplayNames() { return m_displayNames; } AntiMicroX-antimicrox-b300273/src/gui/flashbuttonwidget.h000066400000000000000000000033721471077622000234400ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef FLASHBUTTONWIDGET_H #define FLASHBUTTONWIDGET_H #include class QWidget; class QPaintEvent; class FlashButtonWidget : public QPushButton { Q_OBJECT Q_PROPERTY(bool isflashing READ isButtonFlashing) public: explicit FlashButtonWidget(QWidget *parent = nullptr); explicit FlashButtonWidget(bool displayNames, QWidget *parent = nullptr); bool isButtonFlashing(); void setDisplayNames(bool display); bool isDisplayingNames(); protected: virtual void paintEvent(QPaintEvent *event); virtual QString generateLabel() = 0; virtual void retranslateUi(); bool ifDisplayNames(); public slots: void refreshLabel(); void toggleNameDisplay(); virtual void disableFlashes() = 0; virtual void enableFlashes() = 0; protected slots: void flash(); void unflash(); private: bool isflashing; bool m_displayNames; bool leftAlignText; }; #endif // FLASHBUTTONWIDGET_H AntiMicroX-antimicrox-b300273/src/gui/gamecontrollermappingdialog.cpp000066400000000000000000000566201471077622000260130ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska . */ #include "gamecontrollermappingdialog.h" #include "ui_gamecontrollermappingdialog.h" #include "antimicrosettings.h" #include "common.h" #include "inputdevice.h" #include #include #include #include #include #include #include #include #include #include #include static QHash initAliases() { QHash temp; temp.insert(0, "a"); temp.insert(1, "b"); temp.insert(2, "x"); temp.insert(3, "y"); temp.insert(4, "back"); temp.insert(5, "start"); temp.insert(6, "guide"); temp.insert(7, "leftshoulder"); temp.insert(8, "rightshoulder"); temp.insert(9, "leftstick"); temp.insert(10, "rightstick"); temp.insert(11, "leftx"); temp.insert(12, "lefty"); temp.insert(13, "rightx"); temp.insert(14, "righty"); temp.insert(15, "lefttrigger"); temp.insert(16, "righttrigger"); temp.insert(17, "dpup"); temp.insert(18, "dpleft"); temp.insert(19, "dpdown"); temp.insert(20, "dpright"); return temp; } static QHash initButtonPlacement() { QHash temp; temp.insert(SDL_CONTROLLER_BUTTON_A, 0); temp.insert(SDL_CONTROLLER_BUTTON_B, 1); temp.insert(SDL_CONTROLLER_BUTTON_X, 2); temp.insert(SDL_CONTROLLER_BUTTON_Y, 3); temp.insert(SDL_CONTROLLER_BUTTON_BACK, 4); temp.insert(SDL_CONTROLLER_BUTTON_START, 5); temp.insert(SDL_CONTROLLER_BUTTON_GUIDE, 6); temp.insert(SDL_CONTROLLER_BUTTON_LEFTSHOULDER, 7); temp.insert(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, 8); temp.insert(SDL_CONTROLLER_BUTTON_LEFTSTICK, 9); temp.insert(SDL_CONTROLLER_BUTTON_RIGHTSTICK, 10); temp.insert(SDL_CONTROLLER_BUTTON_DPAD_UP, 17); temp.insert(SDL_CONTROLLER_BUTTON_DPAD_LEFT, 18); temp.insert(SDL_CONTROLLER_BUTTON_DPAD_DOWN, 19); temp.insert(SDL_CONTROLLER_BUTTON_DPAD_RIGHT, 20); return temp; } static QHash initAxisPlacement() { QHash temp; temp.insert(SDL_CONTROLLER_AXIS_LEFTX, 11); temp.insert(SDL_CONTROLLER_AXIS_LEFTY, 12); temp.insert(SDL_CONTROLLER_AXIS_RIGHTX, 13); temp.insert(SDL_CONTROLLER_AXIS_RIGHTY, 14); temp.insert(SDL_CONTROLLER_AXIS_TRIGGERLEFT, 15); temp.insert(SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 16); return temp; } QHash GameControllerMappingDialog::tempaliases = initAliases(); QHash GameControllerMappingDialog::buttonPlacement = initButtonPlacement(); QHash GameControllerMappingDialog::axisPlacement = initAxisPlacement(); GameControllerMappingDialog::GameControllerMappingDialog(InputDevice *device, AntiMicroSettings *settings, QWidget *parent) : QDialog(parent) , ui(new Ui::GameControllerMappingDialog) , helper(device) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); buttonGrabs = 0; usingGameController = false; this->device = device; this->settings = settings; getHelperLocal().moveToThread(device->thread()); PadderCommon::lockInputDevices(); QMetaObject::invokeMethod(device, "haltServices"); QMetaObject::invokeMethod(&helper, "setupDeadZones", Qt::BlockingQueuedConnection); GameController *controller = qobject_cast(device); if (controller != nullptr) { usingGameController = true; populateGameControllerBindings(controller); ui->mappingStringPlainTextEdit->document()->setPlainText(generateSDLMappingString()); } QString tempWindowTitle = QString(tr("Game Controller Mapping (%1) (#%2)")).arg(device->getSDLName()).arg(device->getRealJoyNumber()); setWindowTitle(tempWindowTitle); enableDeviceConnections(); ui->buttonMappingTableWidget->setCurrentCell(0, 0); ui->axisDeadZoneComboBox->clear(); populateAxisDeadZoneComboBox(); currentDeadZoneValue = 20000; int index = ui->axisDeadZoneComboBox->findData(currentDeadZoneValue); if (index != -1) ui->axisDeadZoneComboBox->setCurrentIndex(index); connect(device, &InputDevice::destroyed, this, &GameControllerMappingDialog::obliterate); connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &GameControllerMappingDialog::saveChanges); connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &GameControllerMappingDialog::discardMapping); connect(ui->buttonMappingTableWidget, &QTableWidget::itemSelectionChanged, this, &GameControllerMappingDialog::changeButtonDisplay); connect(ui->axisDeadZoneComboBox, static_cast(&QComboBox::currentIndexChanged), this, &GameControllerMappingDialog::changeAxisDeadZone); connect(this, &GameControllerMappingDialog::finished, this, &GameControllerMappingDialog::enableButtonEvents); PadderCommon::unlockInputDevices(); qInfo() << "Opened GameControllerMappingDialog for mapping device: " << device->getSDLName() << " (#" << device->getRealJoyNumber() << ")"; } GameControllerMappingDialog::~GameControllerMappingDialog() { delete ui; } void GameControllerMappingDialog::buttonAssign(int buttonindex) { // Only perform assignment if no other control is currently active. if (ui->buttonMappingTableWidget->currentRow() > -1) { QTableWidgetItem *item = ui->buttonMappingTableWidget->currentItem(); int column = ui->buttonMappingTableWidget->currentColumn(); int row = ui->buttonMappingTableWidget->currentRow(); if (item == nullptr) { item = new QTableWidgetItem(QString("Button %1").arg(buttonindex + 1)); ui->buttonMappingTableWidget->setItem(row, column, item); } QList templist; templist.append(QVariant(0)); templist.append(QVariant(buttonindex)); QAbstractItemModel *model = ui->buttonMappingTableWidget->model(); QModelIndexList matchlist = model->match(model->index(0, 0), Qt::UserRole, templist, 1, Qt::MatchExactly); foreach (const QModelIndex &index, matchlist) { QTableWidgetItem *existingItem = ui->buttonMappingTableWidget->item(index.row(), index.column()); if (existingItem != nullptr) { existingItem->setText(""); existingItem->setData(Qt::UserRole, QVariant()); } } QList tempvalue; tempvalue.append(QVariant(0)); tempvalue.append(QVariant(buttonindex)); item->setData(Qt::UserRole, tempvalue); item->setText(QString("Button %1").arg(buttonindex + 1)); if (row < (ui->buttonMappingTableWidget->rowCount() - 1)) ui->buttonMappingTableWidget->setCurrentCell(row + 1, column); ui->mappingStringPlainTextEdit->document()->setPlainText(generateSDLMappingString()); } } void GameControllerMappingDialog::axisAssign(int axis, int value) { bool skip = false; if (usingGameController && getEventTriggerAxesLocal().contains(axis) && (value < (-currentDeadZoneValue))) { skip = true; getEventTriggerAxesLocal().removeAll(axis); } if (!skip && (ui->buttonMappingTableWidget->currentRow() > -1)) { QTableWidgetItem *item = ui->buttonMappingTableWidget->currentItem(); int column = ui->buttonMappingTableWidget->currentColumn(); int row = ui->buttonMappingTableWidget->currentRow(); if (usingGameController && (value > currentDeadZoneValue) && !getEventTriggerAxesLocal().contains(axis)) { getEventTriggerAxesLocal().append(axis); } else if (usingGameController && (value < currentDeadZoneValue)) { skip = true; } if (!skip) { if (item == nullptr) { item = new QTableWidgetItem(QString("Axis %1").arg(axis + 1)); ui->buttonMappingTableWidget->setItem(row, column, item); } QList templist; templist.append(QVariant(axis + 1)); templist.append(QVariant(0)); QAbstractItemModel *model = ui->buttonMappingTableWidget->model(); QModelIndexList matchlist = model->match(model->index(0, 0), Qt::UserRole, templist, 1, Qt::MatchExactly); foreach (const QModelIndex &index, matchlist) { QTableWidgetItem *existingItem = ui->buttonMappingTableWidget->item(index.row(), index.column()); if (existingItem != nullptr) { existingItem->setText(""); existingItem->setData(Qt::UserRole, QVariant()); } } QList tempvalue; tempvalue.append(QVariant(axis + 1)); tempvalue.append(QVariant(0)); item->setData(Qt::UserRole, tempvalue); item->setText(QString("Axis %1").arg(axis + 1)); if (row < (ui->buttonMappingTableWidget->rowCount() - 1)) ui->buttonMappingTableWidget->setCurrentCell(row + 1, column); ui->mappingStringPlainTextEdit->document()->setPlainText(generateSDLMappingString()); } } } void GameControllerMappingDialog::dpadAssign(int dpad, int buttonindex) { if (ui->buttonMappingTableWidget->currentRow() > -1) { QTableWidgetItem *item = ui->buttonMappingTableWidget->currentItem(); int column = ui->buttonMappingTableWidget->currentColumn(); int row = ui->buttonMappingTableWidget->currentRow(); if (item == nullptr) { item = new QTableWidgetItem(QString("Hat %1.%2").arg(dpad + 1).arg(buttonindex)); ui->buttonMappingTableWidget->setItem(row, column, item); } QList templist; templist.append(QVariant(-dpad - 1)); templist.append(QVariant(buttonindex)); QAbstractItemModel *model = ui->buttonMappingTableWidget->model(); QModelIndexList matchlist = model->match(model->index(0, 0), Qt::UserRole, templist, 1, Qt::MatchExactly); foreach (const QModelIndex &index, matchlist) { QTableWidgetItem *existingItem = ui->buttonMappingTableWidget->item(index.row(), index.column()); if (existingItem != nullptr) { existingItem->setText(""); existingItem->setData(Qt::UserRole, QVariant()); } } QList tempvalue; tempvalue.append(QVariant(-dpad - 1)); tempvalue.append(QVariant(buttonindex)); item->setData(Qt::UserRole, tempvalue); item->setText(QString("Hat %1.%2").arg(dpad + 1).arg(buttonindex)); if (row < (ui->buttonMappingTableWidget->rowCount() - 1)) ui->buttonMappingTableWidget->setCurrentCell(row + 1, column); ui->mappingStringPlainTextEdit->document()->setPlainText(generateSDLMappingString()); } } void GameControllerMappingDialog::saveChanges() { qInfo() << "Saving changes for GameControllerMappingDialog for device: " << device->getSDLName() << " (#" << device->getRealJoyNumber() << ")"; QString mappingString = generateSDLMappingString(); settings->getLock()->lock(); // settings->setValue(QString("Mappings/").append(device->getGUIDString()), mappingString); // settings->setValue(QString("Mappings/%1%2").arg(device->getGUIDString()).arg("Disable"), "0"); device->convertToUniqueMappSett(settings, QString("Mappings/").append(device->getGUIDString()), QString("Mappings/").append(device->getUniqueIDString())); device->convertToUniqueMappSett(settings, QString("Mappings/%1%2").arg(device->getGUIDString()).arg("Disable"), QString("Mappings/%1%2").arg(device->getUniqueIDString()).arg("Disable")); settings->setValue(QString("Mappings/").append(device->getUniqueIDString()), mappingString); settings->setValue(QString("Mappings/%1%2").arg(device->getUniqueIDString()).arg("Disable"), "0"); settings->sync(); settings->getLock()->unlock(); emit mappingUpdate(mappingString, device); } void GameControllerMappingDialog::populateGameControllerBindings(GameController *controller) { if (controller != nullptr) { qDebug() << "Controller has " << controller->getNumberButtons() << " buttons"; for (int i = 0; i < controller->getNumberButtons(); i++) { int associatedRow = buttonPlacement.value(static_cast(i)); SDL_GameControllerButtonBind bind = controller->getBindForButton(i); QString temptext = bindingString(bind); qDebug() << "Button " << (i + 1) << ": " << temptext; if (!temptext.isEmpty()) { QList tempvariant = bindingValues(bind); QTableWidgetItem *item = new QTableWidgetItem(); ui->buttonMappingTableWidget->setItem(associatedRow, 0, item); item->setText(temptext); item->setData(Qt::UserRole, tempvariant); } } qDebug() << "Controller has " << controller->getNumberAxes() << " axes"; for (int i = 0; i < controller->getNumberAxes(); i++) { int associatedRow = axisPlacement.value(static_cast(i)); SDL_GameControllerButtonBind bind = controller->getBindForAxis(i); QString temptext = bindingString(bind); qDebug() << "Ax " << (i + 1) << ": " << temptext; if (!temptext.isEmpty()) { QList tempvariant = bindingValues(bind); QTableWidgetItem *item = new QTableWidgetItem(); ui->buttonMappingTableWidget->setItem(associatedRow, 0, item); item->setText(temptext); item->setData(Qt::UserRole, tempvariant); } } } } QString GameControllerMappingDialog::bindingString(SDL_GameControllerButtonBind bind) { QString temp = QString(); switch (bind.bindType) { case SDL_CONTROLLER_BINDTYPE_BUTTON: temp.append(QString("Button %1").arg(bind.value.button + 1)); break; case SDL_CONTROLLER_BINDTYPE_AXIS: temp.append(QString("Axis %1").arg(bind.value.axis + 1)); break; case SDL_CONTROLLER_BINDTYPE_HAT: temp.append(QString("Hat %1.%2").arg(bind.value.hat.hat + 1).arg(bind.value.hat.hat_mask)); break; default: break; } return temp; } QList GameControllerMappingDialog::bindingValues(SDL_GameControllerButtonBind bind) { QList temp; switch (bind.bindType) { case SDL_CONTROLLER_BINDTYPE_BUTTON: temp.append(QVariant(0)); temp.append(QVariant(bind.value.button)); break; case SDL_CONTROLLER_BINDTYPE_AXIS: temp.append(QVariant(bind.value.axis + 1)); temp.append(QVariant(0)); break; case SDL_CONTROLLER_BINDTYPE_HAT: temp.append(QVariant(-bind.value.hat.hat - 1)); temp.append(QVariant(bind.value.hat.hat_mask)); break; default: break; } return temp; } void GameControllerMappingDialog::discardMapping(QAbstractButton *button) { disableDeviceConnections(); QDialogButtonBox::ButtonRole currentRole = ui->buttonBox->buttonRole(button); if (currentRole == QDialogButtonBox::DestructiveRole) { QMessageBox msgBox; msgBox.setWindowTitle(tr("Discard Controller Mapping?")); msgBox.setText(tr("Discard mapping for this controller?\n\nIf discarded, the controller will be reverted to a " "joystick once you refresh all joysticks.")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); int status = msgBox.exec(); if (status == QMessageBox::Yes) { removeControllerMapping(); close(); } else { enableDeviceConnections(); } } } void GameControllerMappingDialog::removeControllerMapping() { settings->getLock()->lock(); settings->beginGroup("Mappings"); // settings->remove(device->getGUIDString()); settings->remove(device->getUniqueIDString()); // settings->remove(QString("%1Disable").arg(device->getGUIDString())); settings->remove(QString("%1Disable").arg(device->getUniqueIDString())); settings->endGroup(); settings->sync(); settings->getLock()->unlock(); } void GameControllerMappingDialog::enableDeviceConnections() { connect(device, &InputDevice::rawButtonClick, this, &GameControllerMappingDialog::buttonAssign); connect(device, &InputDevice::rawButtonRelease, this, &GameControllerMappingDialog::buttonRelease); connect(device, &InputDevice::rawAxisMoved, this, &GameControllerMappingDialog::updateLastAxisLineEditRaw); connect(device, &InputDevice::rawAxisActivated, this, &GameControllerMappingDialog::axisAssign); connect(device, &InputDevice::rawAxisReleased, this, &GameControllerMappingDialog::axisRelease); connect(device, &InputDevice::rawDPadButtonClick, this, &GameControllerMappingDialog::dpadAssign); connect(device, &InputDevice::rawDPadButtonRelease, this, &GameControllerMappingDialog::dpadRelease); } void GameControllerMappingDialog::disableDeviceConnections() { disconnect(device, &InputDevice::rawButtonClick, this, nullptr); disconnect(device, &InputDevice::rawButtonRelease, this, nullptr); disconnect(device, &InputDevice::rawAxisMoved, this, nullptr); disconnect(device, &InputDevice::rawAxisActivated, this, nullptr); disconnect(device, &InputDevice::rawAxisReleased, this, nullptr); disconnect(device, &InputDevice::rawDPadButtonClick, this, nullptr); disconnect(device, &InputDevice::rawDPadButtonRelease, this, nullptr); } void GameControllerMappingDialog::enableButtonEvents(int code) { Q_UNUSED(code); bool invoked = QMetaObject::invokeMethod(&helper, "restoreDeviceDeadZones", Qt::BlockingQueuedConnection); if (invoked) qDebug() << "the member restoreDeviceDeadZones could be invoked"; else qDebug() << "the member restoreDeviceDeadZones could not be invoked"; // QMetaObject::invokeMethod(&helper, "restoreDeviceDeadZones", Qt::BlockingQueuedConnection); } QString GameControllerMappingDialog::generateSDLMappingString() { QStringList templist = QStringList(); // templist.append(device->getGUIDString()); templist.append(device->getUniqueIDString()); templist.append(device->getSDLName()); templist.append(QString("platform:").append(device->getSDLPlatform())); for (int i = 0; i < ui->buttonMappingTableWidget->rowCount(); i++) { QTableWidgetItem *item = ui->buttonMappingTableWidget->item(i, 0); if (item != nullptr) { QString mapNative = QString(); QList tempassociation = item->data(Qt::UserRole).toList(); if (tempassociation.size() == 2) { int bindingType = tempassociation.value(0).toInt(); if (bindingType == 0) { mapNative.append("b"); mapNative.append(QString::number(tempassociation.value(1).toInt())); } else if (bindingType > 0) { mapNative.append("a"); mapNative.append(QString::number(tempassociation.value(0).toInt() - 1)); } else if (bindingType < 0) { mapNative.append("h"); mapNative.append(QString::number(tempassociation.value(0).toInt() + 1)); mapNative.append(".").append(QString::number(tempassociation.value(1).toInt())); } } if (!mapNative.isEmpty()) { QString sdlButtonName = tempaliases.value(i); QString temp = QString("%1:%2").arg(sdlButtonName).arg(mapNative); templist.append(temp); } } } return templist.join(",").append(","); } void GameControllerMappingDialog::obliterate() { disconnect(this, &GameControllerMappingDialog::finished, this, &GameControllerMappingDialog::enableButtonEvents); this->done(QDialogButtonBox::DestructiveRole); } void GameControllerMappingDialog::changeButtonDisplay() { ui->gameControllerDisplayWidget->setActiveButton(ui->buttonMappingTableWidget->currentRow()); } /** * @brief TODO: Possibly remove. This was used for decrementing a reference * count. * @param axis * @param value */ void GameControllerMappingDialog::axisRelease(int axis, int value) { Q_UNUSED(axis); Q_UNUSED(value); } /** * @brief TODO: Possibly remove. This was used for decrementing a reference * count. * @param buttonindex */ void GameControllerMappingDialog::buttonRelease(int buttonindex) { Q_UNUSED(buttonindex); } /** * @brief TODO: Possibly remove. This was used for decrementing a reference * count. * @param dpad * @param buttonindex */ void GameControllerMappingDialog::dpadRelease(int dpad, int buttonindex) { Q_UNUSED(dpad); Q_UNUSED(buttonindex); } void GameControllerMappingDialog::populateAxisDeadZoneComboBox() { for (int i = 0; i < 28; i++) { int temp = (i * 1000) + 5000; ui->axisDeadZoneComboBox->addItem(QString::number(temp), temp); } } void GameControllerMappingDialog::changeAxisDeadZone(int index) { int value = ui->axisDeadZoneComboBox->itemData(index).toInt(); if ((value >= 5000) && (value <= 32000)) { QMetaObject::invokeMethod(&helper, "raiseDeadZones", Qt::BlockingQueuedConnection, Q_ARG(int, value)); currentDeadZoneValue = value; } } void GameControllerMappingDialog::updateLastAxisLineEdit(JoyAxis *tempAxis, int value) { if (abs(value) >= 2000) { QString axisText = QString(); if (device->isGameController()) { GameController *controller = qobject_cast(device); axisText = QString("%1: %2").arg(controller->getBindStringForAxis(tempAxis->getIndex(), true)).arg(value); } else { axisText = QString("Axis %1: %2").arg(tempAxis->getRealJoyIndex()).arg(value); } ui->lastAxisEventLineEdit->setText(axisText); } } void GameControllerMappingDialog::updateLastAxisLineEditRaw(int index, int value) { if (abs(value) >= 2000) { QString axisText = QString("Axis %1: %2").arg(index + 1).arg(value); ui->lastAxisEventLineEdit->setText(axisText); } } GameControllerMappingDialogHelper &GameControllerMappingDialog::getHelperLocal() { return helper; } QList &GameControllerMappingDialog::getEventTriggerAxesLocal() { return eventTriggerAxes; } AntiMicroX-antimicrox-b300273/src/gui/gamecontrollermappingdialog.h000066400000000000000000000060041471077622000254470ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GAMECONTROLLERMAPPINGDIALOG_H #define GAMECONTROLLERMAPPINGDIALOG_H #include "gamecontroller/gamecontroller.h" #include "uihelpers/gamecontrollermappingdialoghelper.h" #include class InputDevice; class AntiMicroSettings; class QWidget; class QAbstractButton; namespace Ui { class GameControllerMappingDialog; } class GameControllerMappingDialog : public QDialog { Q_OBJECT public: explicit GameControllerMappingDialog(InputDevice *device, AntiMicroSettings *settings, QWidget *parent = nullptr); ~GameControllerMappingDialog(); static QHash tempaliases; static QHash buttonPlacement; static QHash axisPlacement; protected: void populateGameControllerBindings(GameController *controller); void removeControllerMapping(); void enableDeviceConnections(); void disableDeviceConnections(); QString generateSDLMappingString(); void populateAxisDeadZoneComboBox(); QString bindingString(SDL_GameControllerButtonBind bind); QList bindingValues(SDL_GameControllerButtonBind bind); private: Ui::GameControllerMappingDialog *ui; signals: void mappingUpdate(QString mapping, InputDevice *device); private slots: void buttonAssign(int buttonindex); void axisAssign(int axis, int value); void dpadAssign(int dpad, int buttonindex); void buttonRelease(int buttonindex); void axisRelease(int axis, int value); void dpadRelease(int dpad, int buttonindex); void saveChanges(); void discardMapping(QAbstractButton *button); void enableButtonEvents(int code); void obliterate(); void changeButtonDisplay(); void changeAxisDeadZone(int index); void updateLastAxisLineEdit(JoyAxis *tempAxis, int value); void updateLastAxisLineEditRaw(int index, int value); private: GameControllerMappingDialogHelper &getHelperLocal(); QList &getEventTriggerAxesLocal(); InputDevice *device; AntiMicroSettings *settings; int buttonGrabs; QList eventTriggerAxes; GameControllerMappingDialogHelper helper; int currentDeadZoneValue; bool usingGameController; }; #endif // GAMECONTROLLERMAPPINGDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/gamecontrollermappingdialog.ui000066400000000000000000000316571471077622000256510ustar00rootroot00000000000000 GameControllerMappingDialog 0 0 918 600 600 400 Game Controller Mapping 40 20 <html><head/><body><p>antimicrox makes use of the <a href="https://wiki.libsdl.org/CategoryGameController"><span style=" text-decoration: underline; color:#0057ae;">Game Controller API</span></a> provided by SDL 2 in order to abstract various gamepads to fit a unified standard. In order to make a button assignment, please highlight the mapping cell for the appropriate button row below. You can then press a button or move an axis on your gamepad and the cell will update with the physical button or axis that will be used.</p><p>antimicrox will use the mapping that you specify to save a mapping string that will be loaded into SDL.</p></body></html> true true QFrame::Sunken 1 true QAbstractItemView::NoEditTriggers false false false QAbstractItemView::SingleSelection QAbstractItemView::SelectItems Qt::ElideRight true Qt::SolidLine false true true 21 1 true false 100 true true true false 20 30 true false false A B X Y Back Start Guide Left Shoulder Right Shoulder Left Stick Click Right Stick Click Left Stick X Left Stick Y Right Stick X Right Stick Y Left Trigger Right Trigger DPad Up DPad Left DPad Down DPad Right Mapping 75 true SDL 2 Game Controller Mapping String 0 0 0 0 16777215 100 true 20 300 200 Last Axis Event: true Current Axis Detection Dead Zone: 5000 10000 15000 20000 25000 30000 32000 Qt::Vertical QSizePolicy::Fixed 20 130 Qt::Horizontal Qt::Horizontal QDialogButtonBox::Close|QDialogButtonBox::Discard|QDialogButtonBox::Save GameControllerExample QWidget
gamecontrollerexample.h
1
buttonBox accepted() GameControllerMappingDialog accept() 248 254 157 274 buttonBox rejected() GameControllerMappingDialog reject() 316 260 286 274
AntiMicroX-antimicrox-b300273/src/gui/joyaxiswidget.cpp000066400000000000000000000065311471077622000231300ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joyaxiswidget.h" #include "joyaxis.h" #include "joyaxiscontextmenu.h" #include JoyAxisWidget::JoyAxisWidget(JoyAxis *axis, bool displayNames, QWidget *parent) : FlashButtonWidget(displayNames, parent) { m_axis = axis; refreshLabel(); enableFlashes(); this->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &JoyAxisWidget::customContextMenuRequested, this, &JoyAxisWidget::showContextMenu); JoyAxisButton *nAxisButton = m_axis->getNAxisButton(); JoyAxisButton *pAxisButton = m_axis->getPAxisButton(); tryFlash(); connect(m_axis, &JoyAxis::throttleChanged, this, &JoyAxisWidget::refreshLabel); connect(m_axis, &JoyAxis::axisNameChanged, this, &JoyAxisWidget::refreshLabel); connect(nAxisButton, &JoyAxisButton::propertyUpdated, this, &JoyAxisWidget::refreshLabel); connect(pAxisButton, &JoyAxisButton::propertyUpdated, this, &JoyAxisWidget::refreshLabel); connect(nAxisButton, &JoyAxisButton::activeZoneChanged, this, &JoyAxisWidget::refreshLabel); connect(pAxisButton, &JoyAxisButton::activeZoneChanged, this, &JoyAxisWidget::refreshLabel); m_axis->establishPropertyUpdatedConnection(); nAxisButton->establishPropertyUpdatedConnections(); pAxisButton->establishPropertyUpdatedConnections(); } JoyAxis *JoyAxisWidget::getAxis() const { return m_axis; } void JoyAxisWidget::disableFlashes() { disconnect(m_axis, &JoyAxis::active, this, &JoyAxisWidget::flash); disconnect(m_axis, &JoyAxis::released, this, &JoyAxisWidget::unflash); this->unflash(); } void JoyAxisWidget::enableFlashes() { connect(m_axis, &JoyAxis::active, this, &JoyAxisWidget::flash, Qt::QueuedConnection); connect(m_axis, &JoyAxis::released, this, &JoyAxisWidget::unflash, Qt::QueuedConnection); } /** * @brief Generate the string that will be displayed on the button * @return Display string */ QString JoyAxisWidget::generateLabel() { QString temp = m_axis->getName(false, ifDisplayNames()).replace("&", "&&"); qDebug() << "Name of joy axis is: " << temp; return temp; } void JoyAxisWidget::showContextMenu(const QPoint &point) { QPoint globalPos = this->mapToGlobal(point); JoyAxisContextMenu *contextMenu = new JoyAxisContextMenu(m_axis, this); contextMenu->buildMenu(); contextMenu->popup(globalPos); } void JoyAxisWidget::tryFlash() { JoyAxisButton *nAxisButton = m_axis->getNAxisButton(); JoyAxisButton *pAxisButton = m_axis->getPAxisButton(); if (nAxisButton->getButtonState() || pAxisButton->getButtonState()) { flash(); } } AntiMicroX-antimicrox-b300273/src/gui/joyaxiswidget.h000066400000000000000000000026101471077622000225670ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYAXISWIDGET_H #define JOYAXISWIDGET_H #include "flashbuttonwidget.h" class JoyAxis; class QWidget; class JoyAxisWidget : public FlashButtonWidget { Q_OBJECT public: explicit JoyAxisWidget(JoyAxis *axis, bool displayNames, QWidget *parent = 0); JoyAxis *getAxis() const; void tryFlash(); protected: virtual QString generateLabel() override; public slots: void disableFlashes() override; void enableFlashes() override; private slots: void showContextMenu(const QPoint &point); private: JoyAxis *m_axis; }; #endif // JOYAXISWIDGET_H AntiMicroX-antimicrox-b300273/src/gui/joybuttonwidget.cpp000066400000000000000000000050771471077622000235030ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joybuttonwidget.h" #include "joybuttoncontextmenu.h" #include "joybuttontypes/joybutton.h" #include #include #include JoyButtonWidget::JoyButtonWidget(JoyButton *button, bool displayNames, QWidget *parent) : FlashButtonWidget(displayNames, parent) { m_button = button; refreshLabel(); enableFlashes(); tryFlash(); this->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &JoyButtonWidget::customContextMenuRequested, this, &JoyButtonWidget::showContextMenu); connect(button, &JoyButton::propertyUpdated, this, &JoyButtonWidget::refreshLabel); connect(button, &JoyButton::activeZoneChanged, this, &JoyButtonWidget::refreshLabel); } JoyButton *JoyButtonWidget::getJoyButton() const { return m_button; } void JoyButtonWidget::disableFlashes() { disconnect(m_button, &JoyButton::clicked, this, &JoyButtonWidget::flash); disconnect(m_button, &JoyButton::released, this, &JoyButtonWidget::unflash); this->unflash(); } void JoyButtonWidget::enableFlashes() { connect(m_button, &JoyButton::clicked, this, &JoyButtonWidget::flash, Qt::QueuedConnection); connect(m_button, &JoyButton::released, this, &JoyButtonWidget::unflash, Qt::QueuedConnection); } QString JoyButtonWidget::generateLabel() { QString temp = m_button->getName(false, ifDisplayNames()).replace("&", "&&"); qDebug() << "Name of joy button is: " << temp; return temp; } void JoyButtonWidget::showContextMenu(const QPoint &point) { QPoint globalPos = this->mapToGlobal(point); JoyButtonContextMenu *contextMenu = new JoyButtonContextMenu(m_button, this); contextMenu->buildMenu(); contextMenu->popup(globalPos); } void JoyButtonWidget::tryFlash() { if (m_button->getButtonState()) flash(); } AntiMicroX-antimicrox-b300273/src/gui/joybuttonwidget.h000066400000000000000000000026431471077622000231440ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYBUTTONWIDGET_H #define JOYBUTTONWIDGET_H #include "flashbuttonwidget.h" class JoyButton; class QWidget; class JoyButtonWidget : public FlashButtonWidget { Q_OBJECT public: explicit JoyButtonWidget(JoyButton *button, bool displayNames, QWidget *parent = 0); JoyButton *getJoyButton() const; void tryFlash(); protected: virtual QString generateLabel() override; public slots: void disableFlashes() override; void enableFlashes() override; private slots: void showContextMenu(const QPoint &point); private: JoyButton *m_button; }; #endif // JOYBUTTONWIDGET_H AntiMicroX-antimicrox-b300273/src/gui/joycontrolstickeditdialog.cpp000066400000000000000000000745241471077622000255330ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joycontrolstickeditdialog.h" #include "ui_joycontrolstickeditdialog.h" #include "antkeymapper.h" #include "buttoneditdialog.h" #include "common.h" #include "event.h" #include "inputdevice.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joybuttontypes/joycontrolstickmodifierbutton.h" #include "joycontrolstick.h" #include "mousedialog/mousecontrolsticksettingsdialog.h" #include "setjoystick.h" #include #include #include #include #include JoyControlStickEditDialog::JoyControlStickEditDialog(JoyControlStick *stick, bool keypadUnlocked, QWidget *parent) : QDialog(parent, Qt::Window) , ui(new Ui::JoyControlStickEditDialog) , helper(stick) { ui->setupUi(this); this->keypadUnlocked = keypadUnlocked; setAttribute(Qt::WA_DeleteOnClose); auto min_width = ui->xCoordinateLabel->fontMetrics().boundingRect(QString("X.XXXXXXXXX")).width(); ui->xCoordinateLabel->setMinimumWidth(min_width); this->stick = stick; getHelperLocal().moveToThread(stick->thread()); PadderCommon::inputDaemonMutex.lock(); updateWindowTitleStickName(); ui->deadZoneSlider->setValue(stick->getDeadZone()); ui->deadZoneSpinBox->setValue(stick->getDeadZone()); ui->maxZoneSlider->setValue(stick->getMaxZone()); ui->maxZoneSpinBox->setValue(stick->getMaxZone()); ui->modifierZoneSlider->setValue(stick->getModifierZone()); ui->modifierZoneSpinBox->setValue(stick->getModifierZone()); ui->modifierZoneInvertedCheckBox->setCheckState(stick->getModifierZoneInverted() ? Qt::Checked : Qt::Unchecked); ui->diagonalRangeSlider->setValue(stick->getDiagonalRange()); ui->diagonalRangeSpinBox->setValue(stick->getDiagonalRange()); QString xCoorString = QString::number(stick->getXCoordinate()); if (stick->getCircleAdjust() > 0.0) { xCoorString.append(QString(" (%1)").arg(stick->getCircleXCoordinate())); } ui->xCoordinateLabel->setText(xCoorString); QString yCoorString = QString::number(stick->getYCoordinate()); if (stick->getCircleAdjust() > 0.0) { yCoorString.append(QString(" (%1)").arg(stick->getCircleYCoordinate())); } ui->yCoordinateLabel->setText(yCoorString); ui->distanceLabel->setText(QString::number(stick->getAbsoluteRawDistance())); ui->diagonalLabel->setText(QString::number(stick->calculateBearing())); switch (stick->getJoyMode()) { case JoyControlStick::StandardMode: { ui->joyModeComboBox->setCurrentIndex(0); break; } case JoyControlStick::EightWayMode: { ui->joyModeComboBox->setCurrentIndex(1); break; } case JoyControlStick::FourWayCardinal: { ui->joyModeComboBox->setCurrentIndex(2); ui->diagonalRangeSlider->setEnabled(false); ui->diagonalRangeSpinBox->setEnabled(false); break; } case JoyControlStick::FourWayDiagonal: { ui->joyModeComboBox->setCurrentIndex(3); ui->diagonalRangeSlider->setEnabled(false); ui->diagonalRangeSpinBox->setEnabled(false); break; } } ui->stickStatusBoxWidget->setStick(stick); selectCurrentPreset(); ui->stickNameLineEdit->setText(stick->getStickName()); double validDistance = stick->getDistanceFromDeadZone() * 100.0; ui->fromSafeZoneValueLabel->setText(QString::number(validDistance)); double circleValue = stick->getCircleAdjust(); ui->squareStickSlider->setValue(circleValue * 100); ui->squareStickSpinBox->setValue(circleValue * 100); int stickDelay = stick->getStickDelay(); ui->stickDelaySlider->setValue(stickDelay * .1); ui->stickDelayDoubleSpinBox->setValue(stickDelay * .001); ui->modifierPushButton->setText(stick->getModifierButton()->getSlotsSummary()); stick->getModifierButton()->establishPropertyUpdatedConnections(); update(); updateGeometry(); PadderCommon::inputDaemonMutex.unlock(); connect(ui->presetsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &JoyControlStickEditDialog::implementPresets); connect(ui->joyModeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &JoyControlStickEditDialog::implementModes); connect(ui->deadZoneSlider, &QSlider::valueChanged, ui->deadZoneSpinBox, &QSpinBox::setValue); connect(ui->maxZoneSlider, &QSlider::valueChanged, ui->maxZoneSpinBox, &QSpinBox::setValue); connect(ui->diagonalRangeSlider, &QSlider::valueChanged, ui->diagonalRangeSpinBox, &QSpinBox::setValue); connect(ui->squareStickSlider, &QSlider::valueChanged, ui->squareStickSpinBox, &QSpinBox::setValue); connect(ui->deadZoneSpinBox, static_cast(&QSpinBox::valueChanged), ui->deadZoneSlider, &QSlider::setValue); connect(ui->maxZoneSpinBox, static_cast(&QSpinBox::valueChanged), ui->maxZoneSlider, &QSlider::setValue); connect(ui->maxZoneSpinBox, static_cast(&QSpinBox::valueChanged), this, &JoyControlStickEditDialog::checkMaxZone); connect(ui->diagonalRangeSpinBox, static_cast(&QSpinBox::valueChanged), ui->diagonalRangeSlider, &QSlider::setValue); connect(ui->squareStickSpinBox, static_cast(&QSpinBox::valueChanged), ui->squareStickSlider, &QSlider::setValue); connect(ui->stickDelaySlider, &QSlider::valueChanged, &helper, &JoyControlStickEditDialogHelper::updateControlStickDelay); connect(ui->deadZoneSpinBox, static_cast(&QSpinBox::valueChanged), stick, &JoyControlStick::setDeadZone); connect(ui->diagonalRangeSpinBox, static_cast(&QSpinBox::valueChanged), stick, &JoyControlStick::setDiagonalRange); connect(ui->squareStickSpinBox, static_cast(&QSpinBox::valueChanged), this, &JoyControlStickEditDialog::changeCircleAdjust); connect(stick, &JoyControlStick::stickDelayChanged, this, &JoyControlStickEditDialog::updateStickDelaySpinBox); connect(ui->stickDelayDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &JoyControlStickEditDialog::updateStickDelaySlider); connect(stick, &JoyControlStick::moved, this, &JoyControlStickEditDialog::refreshStickStats); connect(ui->mouseSettingsPushButton, &QPushButton::clicked, this, &JoyControlStickEditDialog::openMouseSettingsDialog); connect(ui->stickNameLineEdit, &QLineEdit::textEdited, stick, &JoyControlStick::setStickName); connect(stick, &JoyControlStick::stickNameChanged, this, &JoyControlStickEditDialog::updateWindowTitleStickName); connect(ui->modifierPushButton, &QPushButton::clicked, this, &JoyControlStickEditDialog::openModifierEditDialog); connect(stick->getModifierButton(), &JoyControlStickModifierButton::slotsChanged, this, &JoyControlStickEditDialog::changeModifierSummary); connect(ui->modifierZoneSlider, &QSlider::valueChanged, ui->modifierZoneSpinBox, &QSpinBox::setValue); connect(ui->modifierZoneSpinBox, static_cast(&QSpinBox::valueChanged), ui->modifierZoneSlider, &QSlider::setValue); connect(ui->modifierZoneSpinBox, static_cast(&QSpinBox::valueChanged), stick, &JoyControlStick::setModifierZone); connect(ui->modifierZoneInvertedCheckBox, &QCheckBox::stateChanged, stick, [stick](int state) { stick->setModifierZoneInverted(state == Qt::Checked); }); } // for tests /*JoyControlStickEditDialog::JoyControlStickEditDialog(QWidget *parent) : QDialog(parent, Qt::Window), ui(new Ui::JoyControlStickEditDialog) { helper = new JoyControlStick(); }*/ JoyControlStickEditDialog::~JoyControlStickEditDialog() { delete ui; } void JoyControlStickEditDialog::implementPresets(int index) { JoyButtonSlot *upButtonSlot = nullptr; JoyButtonSlot *downButtonSlot = nullptr; JoyButtonSlot *leftButtonSlot = nullptr; JoyButtonSlot *rightButtonSlot = nullptr; JoyButtonSlot *upLeftButtonSlot = nullptr; JoyButtonSlot *upRightButtonSlot = nullptr; JoyButtonSlot *downLeftButtonSlot = nullptr; JoyButtonSlot *downRightButtonSlot = nullptr; switch (index) { case 1: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); ui->diagonalRangeSlider->setValue(65); break; } case 2: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); ui->diagonalRangeSlider->setValue(65); break; } case 3: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); ui->diagonalRangeSlider->setValue(65); break; } case 4: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); ui->diagonalRangeSlider->setValue(65); break; } case 5: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up), Qt::Key_Up, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down), Qt::Key_Down, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left), Qt::Key_Left, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right), Qt::Key_Right, JoyButtonSlot::JoyKeyboard, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); ui->diagonalRangeSlider->setValue(45); break; } case 6: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W), Qt::Key_W, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S), Qt::Key_S, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A), Qt::Key_A, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D), Qt::Key_D, JoyButtonSlot::JoyKeyboard, this); PadderCommon::inputDaemonMutex.unlock(); ui->joyModeComboBox->setCurrentIndex(0); ui->diagonalRangeSlider->setValue(45); break; } case 7: { PadderCommon::inputDaemonMutex.lock(); if ((ui->joyModeComboBox->currentIndex() == 0) || (ui->joyModeComboBox->currentIndex() == 2)) { upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); } else if (ui->joyModeComboBox->currentIndex() == 1) { upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); } else if (ui->joyModeComboBox->currentIndex() == 3) { upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); } PadderCommon::inputDaemonMutex.unlock(); ui->diagonalRangeSlider->setValue(45); break; } case 0: case 8: { QMetaObject::invokeMethod(&helper, "clearButtonsSlotsEventReset", Qt::BlockingQueuedConnection); ui->diagonalRangeSlider->setValue(45); stick->getDirectionButton(JoyControlStick::StickUp)->buildActiveZoneSummaryString(); stick->getDirectionButton(JoyControlStick::StickDown)->buildActiveZoneSummaryString(); stick->getDirectionButton(JoyControlStick::StickLeft)->buildActiveZoneSummaryString(); stick->getDirectionButton(JoyControlStick::StickRight)->buildActiveZoneSummaryString(); break; } } QHash tempHash; tempHash.insert(JoyControlStick::StickUp, upButtonSlot); tempHash.insert(JoyControlStick::StickDown, downButtonSlot); tempHash.insert(JoyControlStick::StickLeft, leftButtonSlot); tempHash.insert(JoyControlStick::StickRight, rightButtonSlot); tempHash.insert(JoyControlStick::StickLeftUp, upLeftButtonSlot); tempHash.insert(JoyControlStick::StickRightUp, upRightButtonSlot); tempHash.insert(JoyControlStick::StickLeftDown, downLeftButtonSlot); tempHash.insert(JoyControlStick::StickRightDown, downRightButtonSlot); getHelperLocal().setPendingSlots(&tempHash); QMetaObject::invokeMethod(&helper, "setFromPendingSlots", Qt::BlockingQueuedConnection); } void JoyControlStickEditDialog::refreshStickStats(int x, int y) { Q_UNUSED(x); Q_UNUSED(y); PadderCommon::inputDaemonMutex.lock(); QString xCoorString = QString::number(stick->getXCoordinate()); if (stick->getCircleAdjust() > 0.0) { xCoorString.append(QString(" (%1)").arg(stick->getCircleXCoordinate())); } ui->xCoordinateLabel->setText(xCoorString); QString yCoorString = QString::number(stick->getYCoordinate()); if (stick->getCircleAdjust() > 0.0) { yCoorString.append(QString(" (%1)").arg(stick->getCircleYCoordinate())); } ui->yCoordinateLabel->setText(yCoorString); ui->distanceLabel->setText(QString::number(stick->getAbsoluteRawDistance())); ui->diagonalLabel->setText(QString::number(stick->calculateBearing())); double validDistance = stick->getDistanceFromDeadZone() * 100.0; ui->fromSafeZoneValueLabel->setText(QString::number(validDistance)); PadderCommon::inputDaemonMutex.unlock(); } void JoyControlStickEditDialog::checkMaxZone(int value) { if (value > ui->deadZoneSpinBox->value()) { QMetaObject::invokeMethod(stick, "setMaxZone", Q_ARG(int, value)); } } void JoyControlStickEditDialog::implementModes(int index) { PadderCommon::inputDaemonMutex.lock(); stick->releaseButtonEvents(); switch (index) { case 0: { stick->setJoyMode(JoyControlStick::StandardMode); ui->diagonalRangeSlider->setEnabled(true); ui->diagonalRangeSpinBox->setEnabled(true); break; } case 1: { stick->setJoyMode(JoyControlStick::EightWayMode); ui->diagonalRangeSlider->setEnabled(true); ui->diagonalRangeSpinBox->setEnabled(true); break; } case 2: { stick->setJoyMode(JoyControlStick::FourWayCardinal); ui->diagonalRangeSlider->setEnabled(false); ui->diagonalRangeSpinBox->setEnabled(false); break; } case 3: { stick->setJoyMode(JoyControlStick::FourWayDiagonal); ui->diagonalRangeSlider->setEnabled(false); ui->diagonalRangeSpinBox->setEnabled(false); break; } } PadderCommon::inputDaemonMutex.unlock(); } void JoyControlStickEditDialog::selectCurrentPreset() { JoyControlStickButton *upButton = stick->getDirectionButton(JoyControlStick::StickUp); QList *upslots = upButton->getAssignedSlots(); JoyControlStickButton *downButton = stick->getDirectionButton(JoyControlStick::StickDown); QList *downslots = downButton->getAssignedSlots(); JoyControlStickButton *leftButton = stick->getDirectionButton(JoyControlStick::StickLeft); QList *leftslots = leftButton->getAssignedSlots(); JoyControlStickButton *rightButton = stick->getDirectionButton(JoyControlStick::StickRight); QList *rightslots = rightButton->getAssignedSlots(); if ((upslots->length() == 1) && (downslots->length() == 1) && (leftslots->length() == 1) && (rightslots->length() == 1)) { JoyButtonSlot *upslot = upslots->at(0); JoyButtonSlot *downslot = downslots->at(0); JoyButtonSlot *leftslot = leftslots->at(0); JoyButtonSlot *rightslot = rightslots->at(0); if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseUp) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseDown) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseRight)) { ui->presetsComboBox->setCurrentIndex(1); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseUp) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseDown) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseRight) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { ui->presetsComboBox->setCurrentIndex(2); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseDown) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseUp) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseRight)) { ui->presetsComboBox->setCurrentIndex(3); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseDown) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseUp) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseRight) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { ui->presetsComboBox->setCurrentIndex(4); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right))) { ui->presetsComboBox->setCurrentIndex(5); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D))) { ui->presetsComboBox->setCurrentIndex(6); } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6))) { ui->presetsComboBox->setCurrentIndex(7); } } else if ((upslots->length() == 0) && (downslots->length() == 0) && (leftslots->length() == 0) && (rightslots->length() == 0)) { ui->presetsComboBox->setCurrentIndex(8); } } void JoyControlStickEditDialog::updateMouseMode(int index) { PadderCommon::inputDaemonMutex.lock(); if (index == 1) { stick->setButtonsMouseMode(JoyButton::MouseCursor); } else if (index == 2) { stick->setButtonsMouseMode(JoyButton::MouseSpring); } PadderCommon::inputDaemonMutex.unlock(); } void JoyControlStickEditDialog::openMouseSettingsDialog() { ui->mouseSettingsPushButton->setEnabled(false); MouseControlStickSettingsDialog *dialog = new MouseControlStickSettingsDialog(this->stick, this); dialog->show(); connect(this, SIGNAL(finished(int)), dialog, SLOT(close())); connect(dialog, SIGNAL(finished(int)), this, SLOT(enableMouseSettingButton())); } void JoyControlStickEditDialog::enableMouseSettingButton() { ui->mouseSettingsPushButton->setEnabled(true); } void JoyControlStickEditDialog::updateWindowTitleStickName() { QString temp = QString(tr("Set")).append(" "); if (!stick->getStickName().isEmpty()) { temp.append(stick->getPartialName(false, true)); } else { temp.append(stick->getPartialName()); } if (stick->getParentSet()->getIndex() != 0) { int setIndex = stick->getParentSet()->getRealIndex(); temp.append(" [").append(tr("Set %1").arg(setIndex)); QString setName = stick->getParentSet()->getName(); if (!setName.isEmpty()) { temp.append(": ").append(setName); } temp.append("]"); } setWindowTitle(temp); } void JoyControlStickEditDialog::changeCircleAdjust(int value) { QMetaObject::invokeMethod(stick, "setCircleAdjust", Q_ARG(double, value * 0.01)); } /** * @brief Update QDoubleSpinBox value based on updated stick delay value. * @param Delay value obtained from JoyControlStick. */ void JoyControlStickEditDialog::updateStickDelaySpinBox(int value) { double temp = value * 0.001; ui->stickDelayDoubleSpinBox->setValue(temp); } /** * @brief Update QSlider value based on value from QDoubleSpinBox. * @param Value from QDoubleSpinBox. */ void JoyControlStickEditDialog::updateStickDelaySlider(double value) { int temp = value * 100; if (ui->stickDelaySlider->value() != temp) { ui->stickDelaySlider->setValue(temp); } } void JoyControlStickEditDialog::openModifierEditDialog() { ButtonEditDialog *dialog = new ButtonEditDialog(stick->getModifierButton(), stick->getParentSet()->getInputDevice(), keypadUnlocked, this); dialog->show(); } void JoyControlStickEditDialog::changeModifierSummary() { ui->modifierPushButton->setText(stick->getModifierButton()->getSlotsSummary()); } JoyControlStickEditDialogHelper &JoyControlStickEditDialog::getHelperLocal() { return helper; } AntiMicroX-antimicrox-b300273/src/gui/joycontrolstickeditdialog.h000066400000000000000000000041511471077622000251650ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYCONTROLSTICKEDITDIALOG_H #define JOYCONTROLSTICKEDITDIALOG_H #include "uihelpers/joycontrolstickeditdialoghelper.h" #include class JoyControlStick; class QWidget; namespace Ui { class JoyControlStickEditDialog; } class JoyControlStickEditDialog : public QDialog { Q_OBJECT public: explicit JoyControlStickEditDialog(JoyControlStick *stick, bool keypadUnlocked, QWidget *parent = nullptr); // JoyControlStickEditDialog(QWidget *parent = nullptr); ~JoyControlStickEditDialog(); protected: void selectCurrentPreset(); private: Ui::JoyControlStickEditDialog *ui; bool keypadUnlocked; JoyControlStickEditDialogHelper &getHelperLocal(); JoyControlStick *stick; JoyControlStickEditDialogHelper helper; private slots: void implementPresets(int index); void implementModes(int index); void refreshStickStats(int x, int y); void updateMouseMode(int index); void checkMaxZone(int value); void openMouseSettingsDialog(); void enableMouseSettingButton(); void updateWindowTitleStickName(); void changeCircleAdjust(int value); void updateStickDelaySpinBox(int value); void updateStickDelaySlider(double value); void openModifierEditDialog(); void changeModifierSummary(); }; #endif // JOYCONTROLSTICKEDITDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/joycontrolstickeditdialog.ui000066400000000000000000000676561471077622000253760ustar00rootroot00000000000000 JoyControlStickEditDialog 0 0 702 570 0 0 0 0 Dialog JoyControlStickButtonPushButton[isflashing="true"] { background-color: rgb(0, 0, 255); color: rgb(205, 197, 191); } true 20 0 0 200 200 16777215 16777215 0 0 200 200 Qt::Vertical QSizePolicy::Minimum 20 32 0 0 0 0 0 0 0 0 0 0 0 Bearing: 0 0 0 0 0 Distance: 0 0 Y: 0 0 % Safe Zone: 0 0 X: 0 0 0 Qt::Vertical QSizePolicy::Minimum 20 32 Qt::Horizontal QSizePolicy::Minimum 16 0 4 Presets: 282 0 Mouse (Normal) Mouse (Inverted Horizontal) Mouse (Inverted Vertical) Mouse (Inverted Horizontal + Vertical) Arrows Keys: W | A | S | D NumPad None Stick Mode: 282 0 Standard: 8 region stick with two direction buttons active when the stick is in a diagonal region. Eight Way: 8 region stick with each direction having its own dedicated button. Only one button is ever active at at time. Useful for rougelike games. 4 Way Cardinal: 4 region stick with regions corresponding to the cardinal directions of the stick. Useful for menus. 4 Way Diagonal: 4 region stick with each region corresponding to a diagonal zone of the stick. Standard Eight Way 4 Way Cardinal 4 Way Diagonal Qt::Vertical QSizePolicy::Minimum 20 32 4 Modifier: The area (in degrees) that each diagonal region occupies. 1 90 90 Time lapsed before a direction change is taken into effect. 0 100 1 10 0 0 Qt::Horizontal QSlider::TicksBelow 0 Square Stick: Diagonal Range: Percentage to modify a square stick coordinates to confine values to a circle % 0 100 1 0 Dead Zone: Max Zone: Edit button that is active while the stick is active. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. PushButton Modifier Zone: Time lapsed before a direction change is taken into effect. false s 2 1.000000000000000 0.010000000000000 32 0 Dead zone value to use for an analog stick. 1 32737 6000 Qt::Vertical QSizePolicy::Minimum 0 32 Stick Delay: Value when an analog stick is considered moved 100%. 1 32737 100 1000 32000 Qt::Horizontal Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. 1 32737 100 1000 6000 Qt::Horizontal Value when an analog stick is considered moved 100%. 1 32737 32000 200 0 Dead zone value to use for an analog stick. 1 32737 100 1000 6000 Qt::Horizontal Threshold at which the modifier button gets activated. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. 1 32737 6000 Percentage to modify a square stick coordinates to confine values to a circle 0 100 1 10 0 0 Qt::Horizontal The area (in degrees) that each diagonal region occupies. 1 90 Qt::Horizontal Defines if the modifier buttons gets activated when the stick is inside or outside the threshold value. This button is useful for assigning zones with modifier keys that can be used to assign walk/run functionality to an analog stick. Invert Modifier Zone Qt::Vertical QSizePolicy::Minimum 20 32 Na&me: stickNameLineEdit Qt::Horizontal 40 20 Specify the name of an analog stick. Mouse Settings .. Qt::Horizontal Qt::Horizontal QDialogButtonBox::Close JoyControlStickStatusBox QWidget
joycontrolstickstatusbox.h
1
buttonBox accepted() JoyControlStickEditDialog accept() 248 254 157 274 buttonBox rejected() JoyControlStickEditDialog reject() 316 260 286 274
AntiMicroX-antimicrox-b300273/src/gui/joydpadbuttonwidget.cpp000066400000000000000000000031771471077622000243330ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joydpadbuttonwidget.h" #include "joybuttontypes/joybutton.h" #include #include JoyDPadButtonWidget::JoyDPadButtonWidget(JoyButton *button, bool displayNames, QWidget *parent) : JoyButtonWidget(button, displayNames, parent) { // Ensure that JoyDPadButtonWidget::generateLabel is called. refreshLabel(); } /** * @brief Generate the string that will be displayed on the button * @return Display string */ QString JoyDPadButtonWidget::generateLabel() { QString temp = QString(); if (!getJoyButton()->getActionName().isEmpty() && ifDisplayNames()) { temp = getJoyButton()->getActionName(); } else { temp = getJoyButton()->getCalculatedActiveZoneSummary(); } temp.replace("&", "&&"); qDebug() << "Name of joy dpad button is: " << temp; return temp; } AntiMicroX-antimicrox-b300273/src/gui/joydpadbuttonwidget.h000066400000000000000000000023001471077622000237630ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYDPADBUTTONWIDGET_H #define JOYDPADBUTTONWIDGET_H #include "joybuttonwidget.h" class JoyButton; class QWidget; class JoyDPadButtonWidget : public JoyButtonWidget { Q_OBJECT public: explicit JoyDPadButtonWidget(JoyButton *button, bool displayNames, QWidget *parent = nullptr); protected: virtual QString generateLabel() override; }; #endif // JOYDPADBUTTONWIDGET_H AntiMicroX-antimicrox-b300273/src/gui/joysensoreditdialog.cpp000066400000000000000000000252331471077622000243170ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joysensoreditdialog.h" #include "ui_joysensoreditdialog.h" #include "antkeymapper.h" #include "buttoneditdialog.h" #include "common.h" #include "event.h" #include "inputdevice.h" #include "joybuttontypes/joysensorbutton.h" #include "joysensor.h" #include "mousedialog/mousesensorsettingsdialog.h" #include "setjoystick.h" #include #include #include #include #include JoySensorEditDialog::JoySensorEditDialog(JoySensor *sensor, QWidget *parent) : QDialog(parent, Qt::Window) , m_ui(new Ui::JoySensorEditDialog) , m_sensor(sensor) , m_preset(sensor) { m_ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); auto min_width = m_ui->xCoordinateValue->fontMetrics().boundingRect(QString("X.XXXXXXXXXXX")).width(); m_ui->xCoordinateValue->setMinimumWidth(min_width); m_ui->xCoordinateValue->setAlignment(Qt::AlignLeft); int index = 0; int current_preset_index = 0; JoySensorPreset::Preset current_preset = m_preset.currentPreset(); QList presets = m_preset.getAvailablePresets(); for (const auto &preset : presets) { m_ui->presetsComboBox->insertItem(index, m_preset.getPresetName(preset), preset); if (preset == current_preset) current_preset_index = index; } m_ui->presetsComboBox->setCurrentIndex(current_preset_index); PadderCommon::inputDaemonMutex.lock(); updateWindowTitleSensorName(); if (m_sensor->getType() == ACCELEROMETER) { float value; m_ui->accelerationValue->setText(QString::number(m_sensor->calculateDistance())); value = JoySensor::radToDeg(m_sensor->calculatePitch()); m_ui->pitchValue->setText(QString::number(value)); value = JoySensor::radToDeg(m_sensor->calculateRoll()); m_ui->rollValue->setText(QString::number(value)); m_ui->maxZoneSlider->setMaximum(GlobalVariables::JoySensor::ACCEL_MAX); m_ui->maxZoneSpinBox->setMaximum(GlobalVariables::JoySensor::ACCEL_MAX); } else { m_ui->xCoordinateLabel->setText(tr("Roll (°/s)")); m_ui->yCoordinateLabel->setText(tr("Pitch (°/s)")); m_ui->zCoordinateLabel->setText(tr("Yaw (°/s)")); m_ui->accelerationLabel->setVisible(false); m_ui->accelerationValue->setVisible(false); m_ui->pitchLabel->setVisible(false); m_ui->pitchValue->setVisible(false); m_ui->rollLabel->setVisible(false); m_ui->rollValue->setVisible(false); m_ui->maxZoneSlider->setMaximum(GlobalVariables::JoySensor::GYRO_MAX); m_ui->maxZoneSpinBox->setMaximum(GlobalVariables::JoySensor::GYRO_MAX); } m_ui->deadZoneSlider->setValue(m_sensor->getDeadZone()); m_ui->deadZoneSpinBox->setValue(m_sensor->getDeadZone()); m_ui->maxZoneSlider->setValue(m_sensor->getMaxZone()); m_ui->maxZoneSpinBox->setValue(m_sensor->getMaxZone()); m_ui->diagonalRangeSlider->setValue(m_sensor->getDiagonalRange()); m_ui->diagonalRangeSpinBox->setValue(m_sensor->getDiagonalRange()); QString xCoorString = QString::number(m_sensor->getXCoordinate()); m_ui->xCoordinateValue->setText(xCoorString); QString yCoorString = QString::number(m_sensor->getYCoordinate()); m_ui->yCoordinateValue->setText(yCoorString); QString zCoorString = QString::number(m_sensor->getZCoordinate()); m_ui->zCoordinateValue->setText(zCoorString); m_ui->sensorStatusBoxWidget->setSensor(m_sensor); m_ui->sensorNameLineEdit->setText(m_sensor->getSensorName()); double validDistance = m_sensor->getDistanceFromDeadZone() * 100.0; m_ui->fromSafeZoneValueLabel->setText(QString::number(validDistance)); int sensorDelay = m_sensor->getSensorDelay(); m_ui->sensorDelaySlider->setValue(sensorDelay * .1); m_ui->sensorDelayDoubleSpinBox->setValue(sensorDelay * .001); update(); updateGeometry(); PadderCommon::inputDaemonMutex.unlock(); connect(m_ui->presetsComboBox, static_cast(&QComboBox::currentIndexChanged), this, &JoySensorEditDialog::implementPresets); connect(m_ui->deadZoneSlider, &QSlider::valueChanged, m_ui->deadZoneSpinBox, &QDoubleSpinBox::setValue); connect(m_ui->maxZoneSlider, &QSlider::valueChanged, m_ui->maxZoneSpinBox, &QDoubleSpinBox::setValue); connect(m_ui->diagonalRangeSlider, &QSlider::valueChanged, m_ui->diagonalRangeSpinBox, &QSpinBox::setValue); connect(m_ui->sensorDelaySlider, &QSlider::valueChanged, this, &JoySensorEditDialog::updateSensorDelaySpinBox); connect(m_ui->deadZoneSpinBox, static_cast(&QDoubleSpinBox::valueChanged), m_ui->deadZoneSlider, &QSlider::setValue); connect(m_ui->maxZoneSpinBox, static_cast(&QDoubleSpinBox::valueChanged), m_ui->maxZoneSlider, &QSlider::setValue); connect(m_ui->diagonalRangeSpinBox, static_cast(&QSpinBox::valueChanged), m_ui->diagonalRangeSlider, &QSlider::setValue); connect(m_ui->sensorDelayDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &JoySensorEditDialog::updateSensorDelaySlider); connect(m_ui->deadZoneSpinBox, static_cast(&QDoubleSpinBox::valueChanged), m_sensor, &JoySensor::setDeadZone); connect(m_ui->maxZoneSpinBox, static_cast(&QDoubleSpinBox::valueChanged), m_sensor, &JoySensor::setMaxZone); connect(m_ui->diagonalRangeSpinBox, static_cast(&QSpinBox::valueChanged), m_sensor, &JoySensor::setDiagonalRange); connect(m_ui->sensorDelayDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &JoySensorEditDialog::setSensorDelay); connect(m_sensor, &JoySensor::moved, this, &JoySensorEditDialog::updateSensorStats); connect(m_ui->mouseSettingsPushButton, &QPushButton::clicked, this, &JoySensorEditDialog::openMouseSettingsDialog); connect(m_ui->sensorNameLineEdit, &QLineEdit::textEdited, m_sensor, &JoySensor::setSensorName); connect(m_sensor, &JoySensor::sensorNameChanged, this, &JoySensorEditDialog::updateWindowTitleSensorName); } JoySensorEditDialog::~JoySensorEditDialog() { delete m_ui; } /** * @brief Preset combo box event handler. Applies selected preset to underlying sensor. */ void JoySensorEditDialog::implementPresets(int index) { auto preset = static_cast(m_ui->presetsComboBox->itemData(index).toInt()); m_preset.setSensorPreset(preset); m_ui->deadZoneSlider->setValue(m_sensor->getDeadZone()); m_ui->deadZoneSpinBox->setValue(m_sensor->getDeadZone()); m_ui->maxZoneSlider->setValue(m_sensor->getMaxZone()); m_ui->maxZoneSpinBox->setValue(m_sensor->getMaxZone()); m_ui->diagonalRangeSlider->setValue(m_sensor->getDiagonalRange()); m_ui->diagonalRangeSpinBox->setValue(m_sensor->getDiagonalRange()); } /** * @brief Opens sensor mouse settings dialog */ void JoySensorEditDialog::openMouseSettingsDialog() { m_ui->mouseSettingsPushButton->setEnabled(false); MouseSensorSettingsDialog *dialog = new MouseSensorSettingsDialog(m_sensor, this); dialog->show(); connect(this, SIGNAL(finished(int)), dialog, SLOT(close())); connect(dialog, SIGNAL(finished(int)), this, SLOT(enableMouseSettingButton())); } void JoySensorEditDialog::enableMouseSettingButton() { m_ui->mouseSettingsPushButton->setEnabled(true); } /** * @brief Updates the numerical sensor values on the screen */ void JoySensorEditDialog::updateSensorStats(float x, float y, float z) { float value; m_ui->xCoordinateValue->setText(QString::number(x)); m_ui->yCoordinateValue->setText(QString::number(y)); m_ui->zCoordinateValue->setText(QString::number(z)); if (m_sensor->getType() == ACCELEROMETER) { m_ui->accelerationValue->setText(QString::number(m_sensor->calculateDistance(x, y, z))); value = JoySensor::radToDeg(m_sensor->calculatePitch(x, y, z)); m_ui->pitchValue->setText(QString::number(value)); value = JoySensor::radToDeg(m_sensor->calculateRoll(x, y, z)); m_ui->rollValue->setText(QString::number(value)); } double validDistance = m_sensor->getDistanceFromDeadZone(x, y, z) * 100.0; m_ui->fromSafeZoneValueLabel->setText(QString::number(validDistance)); } /** * @brief Shows the sensor name in dialog title */ void JoySensorEditDialog::updateWindowTitleSensorName() { QString temp = QString(tr("Set")).append(" "); if (!m_sensor->getSensorName().isEmpty()) temp.append(m_sensor->getPartialName(false, true)); else temp.append(m_sensor->getPartialName()); if (m_sensor->getParentSet()->getIndex() != 0) { int setIndex = m_sensor->getParentSet()->getRealIndex(); temp.append(" [").append(tr("Set %1").arg(setIndex)); QString setName = m_sensor->getParentSet()->getName(); if (!setName.isEmpty()) { temp.append(": ").append(setName); } temp.append("]"); } setWindowTitle(temp); } /** * @brief Update QDoubleSpinBox value based on updated sensor delay value. * @param Delay value obtained from JoySensor. */ void JoySensorEditDialog::updateSensorDelaySpinBox(int value) { double temp = value / 1000.0; m_ui->sensorDelayDoubleSpinBox->setValue(temp); } /** * @brief Update QSlider value based on value from QDoubleSpinBox. * @param Value from QDoubleSpinBox. */ void JoySensorEditDialog::updateSensorDelaySlider(double value) { int temp = value * 1000; if (m_ui->sensorDelaySlider->value() != temp) m_ui->sensorDelaySlider->setValue(temp); } /** * @brief Sensor delay change event handler * Converts the double value from the SpinBox to int and pass it to JoySensor. */ void JoySensorEditDialog::setSensorDelay(double value) { QMetaObject::invokeMethod(m_sensor, "setSensorDelay", Q_ARG(unsigned int, value * 1000)); } AntiMicroX-antimicrox-b300273/src/gui/joysensoreditdialog.h000066400000000000000000000031311471077622000237550ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "joysensorpreset.h" #include class JoySensor; class QWidget; namespace Ui { class JoySensorEditDialog; } /** * @brief The configuration dialog for a JoySensor itself */ class JoySensorEditDialog : public QDialog { Q_OBJECT public: explicit JoySensorEditDialog(JoySensor *sensor, QWidget *parent = nullptr); ~JoySensorEditDialog(); private: Ui::JoySensorEditDialog *m_ui; bool m_keypad_unlocked; JoySensor *m_sensor; JoySensorPreset m_preset; private slots: void implementPresets(int index); void openMouseSettingsDialog(); void enableMouseSettingButton(); void updateSensorStats(float x, float y, float z); void updateWindowTitleSensorName(); void updateSensorDelaySpinBox(int value); void updateSensorDelaySlider(double value); void setSensorDelay(double value); }; AntiMicroX-antimicrox-b300273/src/gui/joysensoreditdialog.ui000066400000000000000000000530601471077622000241510ustar00rootroot00000000000000 JoySensorEditDialog 0 0 702 570 0 0 0 0 Dialog JoySensorButtonPushButton[isflashing="true"] { background-color: rgb(0, 0, 255); color: rgb(205, 197, 191); } true 20 0 0 200 200 16777215 16777215 0 0 200 200 Qt::Vertical QSizePolicy::Fixed 20 20 0 0 0 0 0 X (m/s^2): 0 0 0 0 0 0 0 0 0 0 0 Acceleration (m/s^2): 0 0 0 0 0 Pitch (°): 0 0 Roll (°): 0 0 Z (m/s^2): 0 0 0 0 0 0 0 Y (m/s^2): 0 0 % Safe Zone: 0 0 0 Qt::Vertical QSizePolicy::Fixed 20 20 10 Presets: 282 0 Qt::Vertical QSizePolicy::MinimumExpanding 20 20 6 Dead Zone: Dead zone value to use for an analog sensor. 1 70 0 1 1 Qt::Horizontal Dead zone value to use for an analog sensor. 2 0.000000000000000 70.000000000000000 0.500000000000000 Max Zone: Value when an analog sensor is considered moved 100%. 0 30 0 10 1 Qt::Horizontal Value when an analog sensor is considered moved 100%. 2 1.000000000000000 30.000000000000000 1.000000000000000 Diagonal Range: The area (in degrees) that each diagonal region occupies. 1 90 Qt::Horizontal The area (in degrees) that each diagonal region occupies. 1 90 90 Sensor Delay: Time lapsed before a direction change is taken into effect. 0 100 1 10 0 0 Qt::Horizontal QSlider::TicksBelow 0 Time lapsed before a direction change is taken into effect. false s 2 1.000000000000000 0.010000000000000 Qt::Vertical QSizePolicy::Fixed 20 20 10 6 Na&me: sensorNameLineEdit Specify the name of an analog sensor. Mouse Settings .. Qt::Horizontal Qt::Horizontal QDialogButtonBox::Close JoySensorStatusBox QWidget
joysensorstatusbox.h
1
buttonBox accepted() JoySensorEditDialog accept() 248 254 157 274 buttonBox rejected() JoySensorEditDialog reject() 316 260 286 274
AntiMicroX-antimicrox-b300273/src/gui/joystickstatuswindow.cpp000066400000000000000000000264731471077622000246000ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joystickstatuswindow.h" #include "ui_joystickstatuswindow.h" #include "common.h" #include "globalvariables.h" #include "inputdevice.h" #include "joybuttonstatusbox.h" #include "joybuttontypes/joydpadbutton.h" #include "joydpad.h" #include "joysensor.h" #include #include #include #include #include #include #include #include JoystickStatusWindow::JoystickStatusWindow(InputDevice *joystick, QWidget *parent) : QDialog(parent) , ui(new Ui::JoystickStatusWindow) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); this->joystick = joystick; PadderCommon::inputDaemonMutex.lock(); setWindowTitle(tr("%1 (#%2) Properties").arg(joystick->getSDLName()).arg(joystick->getRealJoyNumber())); SDL_JoystickPowerLevel powerLevel = SDL_JoystickCurrentPowerLevel(joystick->getJoyHandle()); switch (powerLevel) { case SDL_JOYSTICK_POWER_EMPTY: ui->batteryValueLabel->setText(tr("Empty")); break; case SDL_JOYSTICK_POWER_LOW: ui->batteryValueLabel->setText(tr("Low")); break; case SDL_JOYSTICK_POWER_MEDIUM: ui->batteryValueLabel->setText(tr("Medium")); break; case SDL_JOYSTICK_POWER_FULL: case SDL_JOYSTICK_POWER_MAX: ui->batteryValueLabel->setText(tr("Full")); break; case SDL_JOYSTICK_POWER_UNKNOWN: ui->batteryValueLabel->setText(tr("Unknown")); break; case SDL_JOYSTICK_POWER_WIRED: ui->batteryValueLabel->setText(tr("Wired")); break; default: ui->batteryValueLabel->setText(tr("Different: %1").arg(powerLevel)); WARN() << "Unknown battery level:" << powerLevel; break; } ui->joystickNameLabel->setText(joystick->getSDLName()); ui->joystickNumberLabel->setText(QString::number(joystick->getRealJoyNumber())); ui->joystickAxesLabel->setText(QString::number(joystick->getNumberRawAxes())); ui->joystickButtonsLabel->setText(QString::number(joystick->getNumberRawButtons())); ui->joystickHatsLabel->setText(QString::number(joystick->getNumberRawHats())); if (joystick->hasRawSensor(ACCELEROMETER) && joystick->hasRawSensor(GYROSCOPE)) ui->joystickSensorsLabel->setText(tr("Accelerometer + Gyroscope")); else if (joystick->hasRawSensor(ACCELEROMETER)) ui->joystickSensorsLabel->setText(tr("Accelerometer")); else if (joystick->hasRawSensor(GYROSCOPE)) ui->joystickSensorsLabel->setText(tr("Gyroscope")); else ui->joystickSensorsLabel->setText(tr("None")); joystick->getActiveSetJoystick()->setIgnoreEventState(true); joystick->getActiveSetJoystick()->release(); joystick->resetButtonDownCount(); QVBoxLayout *axesBox = new QVBoxLayout(); axesBox->setSpacing(4); for (int i = 0; i < joystick->getNumberAxes(); i++) { JoyAxis *axis = joystick->getActiveSetJoystick()->getJoyAxis(i); if (axis != nullptr) { QHBoxLayout *hbox = new QHBoxLayout(); QLabel *axisLabel = new QLabel(); axisLabel->setText(tr("Axis %1").arg(axis->getRealJoyIndex())); QProgressBar *axisBar = new QProgressBar(); axisBar->setMinimum(GlobalVariables::JoyAxis::AXISMIN); axisBar->setMaximum(GlobalVariables::JoyAxis::AXISMAX); axisBar->setFormat("%v"); axisBar->setValue(axis->getCurrentRawValue()); hbox->addWidget(axisLabel); hbox->addWidget(axisBar); hbox->addSpacing(10); axesBox->addLayout(hbox); connect(axis, &JoyAxis::moved, axisBar, &QProgressBar::setValue); } } ui->axesScrollArea->setLayout(axesBox); QGridLayout *buttonsGrid = new QGridLayout(); buttonsGrid->setHorizontalSpacing(10); buttonsGrid->setVerticalSpacing(10); int currentRow = 0; int currentColumn = 0; for (int i = 0; i < joystick->getNumberButtons(); i++) { JoyButton *button = joystick->getActiveSetJoystick()->getJoyButton(i); if (button != nullptr) { JoyButtonStatusBox *statusbox = new JoyButtonStatusBox(button); statusbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); buttonsGrid->addWidget(statusbox, currentRow, currentColumn); currentColumn++; if (currentColumn >= 6) { currentRow++; currentColumn = 0; } } } ui->buttonsScrollArea->setLayout(buttonsGrid); QVBoxLayout *hatsBox = new QVBoxLayout(); hatsBox->setSpacing(4); for (int i = 0; i < joystick->getNumberHats(); i++) { JoyDPad *dpad = joystick->getActiveSetJoystick()->getJoyDPad(i); if (dpad != nullptr) { QHBoxLayout *hbox = new QHBoxLayout(); QLabel *dpadLabel = new QLabel(); dpadLabel->setText(tr("Hat %1").arg(dpad->getRealJoyNumber())); QProgressBar *dpadBar = new QProgressBar(); dpadBar->setMinimum(JoyDPadButton::DpadCentered); dpadBar->setMaximum(JoyDPadButton::DpadLeftDown); dpadBar->setFormat("%v"); dpadBar->setValue(dpad->getCurrentDirection()); hbox->addWidget(dpadLabel); hbox->addWidget(dpadBar); hbox->addSpacing(10); hatsBox->addLayout(hbox); connect(dpad, &JoyDPad::active, dpadBar, &QProgressBar::setValue); connect(dpad, &JoyDPad::released, dpadBar, &QProgressBar::setValue); } } hatsBox->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Preferred, QSizePolicy::Fixed)); if (ui->hatsGroupBox->layout()) { delete ui->hatsGroupBox->layout(); } ui->hatsGroupBox->setLayout(hatsBox); QVBoxLayout *sensorsBox = new QVBoxLayout(); sensorsBox->setSpacing(4); for (int i = 0; i < SENSOR_COUNT; ++i) { JoySensorType type = static_cast(i); JoySensor *sensor = joystick->getActiveSetJoystick()->getSensor(type); QProgressBar **axes; if (type == ACCELEROMETER) axes = m_accel_axes; else axes = m_gyro_axes; if (sensor != nullptr) { for (int i = 0; i < 3; ++i) { QHBoxLayout *hbox = new QHBoxLayout(); QLabel *axisLabel = new QLabel(); axes[i] = new QProgressBar(); if (type == ACCELEROMETER) { axes[i]->setMinimum(GlobalVariables::JoySensor::ACCEL_MIN * 1000); axes[i]->setMaximum(GlobalVariables::JoySensor::ACCEL_MAX * 1000); } else { axes[i]->setMinimum(GlobalVariables::JoySensor::GYRO_MIN * 1000); axes[i]->setMaximum(GlobalVariables::JoySensor::GYRO_MAX * 1000); } axes[i]->setFormat("%v"); if (i == 0) { axisLabel->setText(QString("%1 X").arg(sensor->sensorTypeName())); axes[i]->setValue(sensor->getXCoordinate()); } else if (i == 1) { axisLabel->setText(QString("%1 Y").arg(sensor->sensorTypeName())); axes[i]->setValue(sensor->getYCoordinate()); } else { axisLabel->setText(QString("%1 Z").arg(sensor->sensorTypeName())); axes[i]->setValue(sensor->getZCoordinate()); } hbox->addWidget(axisLabel); hbox->addWidget(axes[i]); hbox->addSpacing(10); sensorsBox->addLayout(hbox); } if (type == ACCELEROMETER) { connect(sensor, &JoySensor::moved, this, &JoystickStatusWindow::updateAccelerometerValues); } else { connect(sensor, &JoySensor::moved, this, &JoystickStatusWindow::updateGyroscopeValues); } } } sensorsBox->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Preferred, QSizePolicy::Fixed)); ui->sensorsGroupBox->setLayout(sensorsBox); // QString guidString = joystick->getGUIDString(); // if (!guidString.isEmpty()) // { // ui->guidHeaderLabel->show(); // ui->guidLabel->setText(guidString); // ui->guidLabel->show(); // } // else // { // ui->guidHeaderLabel->hide(); // ui->guidLabel->hide(); // } QString uniqueString = joystick->getUniqueIDString(); if (!uniqueString.isEmpty()) { ui->guidHeaderLabel->show(); ui->guidLabel->setText(uniqueString); ui->guidLabel->show(); } else { ui->guidHeaderLabel->hide(); ui->guidLabel->hide(); } QString usingGameController = tr("No"); if (joystick->isGameController()) { usingGameController = tr("Yes"); } ui->sdlGameControllerLabel->setText(usingGameController); PadderCommon::inputDaemonMutex.unlock(); connect(joystick, &InputDevice::destroyed, this, &JoystickStatusWindow::obliterate); connect(this, &JoystickStatusWindow::finished, this, &JoystickStatusWindow::restoreButtonStates); } JoystickStatusWindow::~JoystickStatusWindow() { delete ui; } void JoystickStatusWindow::restoreButtonStates(int code) { if (code == QDialogButtonBox::AcceptRole) { PadderCommon::inputDaemonMutex.lock(); joystick->getActiveSetJoystick()->setIgnoreEventState(false); joystick->getActiveSetJoystick()->release(); PadderCommon::inputDaemonMutex.unlock(); } } void JoystickStatusWindow::obliterate() { this->done(QDialogButtonBox::DestructiveRole); } /** * @brief Accelerometer "moved" event handler * Updates raw accelerometer values on the screen. */ void JoystickStatusWindow::updateAccelerometerValues(float valueX, float valueY, float valueZ) { m_accel_axes[0]->setValue(valueX * 1000); m_accel_axes[1]->setValue(valueY * 1000); m_accel_axes[2]->setValue(valueZ * 1000); } /** * @brief Gyroscope "moved" event handler * Updates raw gyroscope values on the screen. */ void JoystickStatusWindow::updateGyroscopeValues(float valueX, float valueY, float valueZ) { m_gyro_axes[0]->setValue(JoySensor::radToDeg(valueX) * 1000); m_gyro_axes[1]->setValue(JoySensor::radToDeg(valueY) * 1000); m_gyro_axes[2]->setValue(JoySensor::radToDeg(valueZ) * 1000); } InputDevice *JoystickStatusWindow::getJoystick() const { return joystick; } AntiMicroX-antimicrox-b300273/src/gui/joystickstatuswindow.h000066400000000000000000000033061471077622000242330ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYSTICKSTATUSWINDOW_H #define JOYSTICKSTATUSWINDOW_H #include class InputDevice; class QProgressBar; class QWidget; namespace Ui { class JoystickStatusWindow; } /** * @brief The joystick "Properties" window. * Shows various raw values to the user. */ class JoystickStatusWindow : public QDialog { Q_OBJECT public: explicit JoystickStatusWindow(InputDevice *joystick, QWidget *parent = nullptr); ~JoystickStatusWindow(); InputDevice *getJoystick() const; private: Ui::JoystickStatusWindow *ui; InputDevice *joystick; QProgressBar *m_accel_axes[3]; QProgressBar *m_gyro_axes[3]; private slots: void restoreButtonStates(int code); void obliterate(); void updateAccelerometerValues(float valueX, float valueY, float valueZ); void updateGyroscopeValues(float valueX, float valueY, float valueZ); }; #endif // JOYSTICKSTATUSWINDOW_H AntiMicroX-antimicrox-b300273/src/gui/joystickstatuswindow.ui000066400000000000000000000366061471077622000244320ustar00rootroot00000000000000 JoystickStatusWindow Qt::ApplicationModal 0 0 580 480 580 440 Properties JoyButtonStatusBox { border: 1px solid rgb(0, 0, 0); } JoyButtonStatusBox[isflashing="true"] { background-color: rgb(0, 0, 255); color: rgb(205, 197, 191); } true 200 0 Details 75 true Name: %1 10 75 true Number: %1 10 75 true Axes: %1 10 75 true Buttons: %1 10 75 true Hats: %1 10 75 true Sensors: %1 10 0 0 0 0 0 20 75 true Battery: 0 14 Unknown true 75 true GUID: %1 true 10 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse true 75 true Game Controller: %1 true 10 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Axes 4 4 4 4 QFrame::NoFrame QFrame::Sunken 1 true 0 0 346 120 Qt::Vertical QSizePolicy::Fixed 20 10 Buttons 4 4 4 4 false QFrame::NoFrame true 0 0 346 120 Qt::Vertical QSizePolicy::Fixed 20 10 Hats 4 4 4 14 Sensors Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() JoystickStatusWindow accept() 248 254 157 274 buttonBox rejected() JoystickStatusWindow reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/joytabwidget.cpp000066400000000000000000002653211471077622000227360ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joytabwidget.h" #include "advancestickassignmentdialog.h" #include "antimicrosettings.h" #include "axiseditdialog.h" #include "buttoneditdialog.h" #include "common.h" #include "dpadpushbuttongroup.h" #include "extraprofilesettingsdialog.h" #include "globalvariables.h" #include "inputdevice.h" #include "joyaxiswidget.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joybuttontypes/joydpadbutton.h" #include "joybuttontypes/joysensorbutton.h" #include "joybuttonwidget.h" #include "joycontrolstick.h" #include "joydpad.h" #include "joysensor.h" #include "joystick.h" #include "quicksetdialog.h" #include "sensorpushbuttongroup.h" #include "setnamesdialog.h" #include "stickpushbuttongroup.h" #include "vdpad.h" #include "xmlconfigreader.h" #include "xmlconfigwriter.h" #include "gamecontroller/gamecontroller.h" #include "gamecontrollermappingdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include bool JoyTabWidget::changedNotSaved = false; JoyTabWidget::JoyTabWidget(InputDevice *joystick, AntiMicroSettings *settings, QWidget *parent) : QWidget(parent) , m_joystick(joystick) , m_settings(settings) , tabHelper(joystick) { tabHelper.moveToThread(joystick->thread()); verticalLayout = new QVBoxLayout(this); verticalLayout->setContentsMargins(4, 4, 4, 4); configHorizontalLayout = new QHBoxLayout(); configBox = new QComboBox(this); configBox->addItem(tr(""), ""); QStringList themesPaths = QIcon::themeSearchPaths(); for (int i = 0; i < themesPaths.count(); i++) { qDebug() << "themePath: " << themesPaths.at(i); } configBox->setObjectName(QString::fromUtf8("configBox")); configBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); configHorizontalLayout->addWidget(configBox); batteryIcon = new QLabel("", this); batteryIcon->setToolTip(tr("Battery level of controller")); batteryIcon->setObjectName(QString::fromUtf8("battIcon")); batteryIcon->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); configHorizontalLayout->addWidget(batteryIcon); m_battery_updater = new QTimer(this); connect(m_battery_updater, &QTimer::timeout, this, &JoyTabWidget::updateBatteryIcon); m_battery_updater->start(5000); spacer1 = new QSpacerItem(30, 20, QSizePolicy::Fixed, QSizePolicy::Fixed); configHorizontalLayout->addItem(spacer1); removeButton = new QPushButton(tr("Remove"), this); removeButton->setObjectName(QString::fromUtf8("removeButton")); removeButton->setToolTip(tr("Remove configuration from recent list.")); removeButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); removeButton->setIcon(PadderCommon::loadIcon("user-trash", ":/images/actions/edit_clear_list.png")); configHorizontalLayout->addWidget(removeButton); loadButton = new QPushButton(tr("Load"), this); loadButton->setObjectName(QString::fromUtf8("loadButton")); loadButton->setToolTip(tr("Load configuration file.")); loadButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); loadButton->setIcon(PadderCommon::loadIcon("document-open", ":/images/actions/document_open.png")); configHorizontalLayout->addWidget(loadButton); saveButton = new QPushButton(tr("Save"), this); saveButton->setObjectName(QString::fromUtf8("saveButton")); saveButton->setToolTip(tr("Save changes to configuration file.")); saveButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); saveButton->setIcon(PadderCommon::loadIcon("document-save", ":/images/actions/document_save.png")); configHorizontalLayout->addWidget(saveButton); saveAsButton = new QPushButton(tr("Save As"), this); saveAsButton->setObjectName(QString::fromUtf8("saveAsButton")); saveAsButton->setToolTip(tr("Save changes to a new configuration file.")); saveAsButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); saveAsButton->setIcon(PadderCommon::loadIcon("document-save-as", ":/images/actions/document_save_as.png")); configHorizontalLayout->addWidget(saveAsButton); verticalLayout->addLayout(configHorizontalLayout); verticalLayout->setStretchFactor(configHorizontalLayout, 1); spacer2 = new QSpacerItem(20, 5, QSizePolicy::Fixed, QSizePolicy::Fixed); verticalLayout->addItem(spacer2); verticalSpacer_2 = new QSpacerItem(20, 5, QSizePolicy::Minimum, QSizePolicy::Fixed); verticalLayout->addItem(verticalSpacer_2); stackedWidget_2 = new QStackedWidget(this); stackedWidget_2->setObjectName(QString::fromUtf8("stackedWidget_2")); page = new QWidget(); page->setObjectName(QString::fromUtf8("page")); QVBoxLayout *tempVBoxLayout = new QVBoxLayout(page); QScrollArea *scrollArea = new QScrollArea(); scrollArea->setObjectName(QString::fromUtf8("scrollArea1")); QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); scrollArea->setSizePolicy(sizePolicy); scrollArea->setWidgetResizable(true); QWidget *scrollAreaWidgetContents1 = new QWidget(); scrollAreaWidgetContents1->setObjectName(QString::fromUtf8("scrollAreaWidgetContents1")); gridLayout = new QGridLayout(scrollAreaWidgetContents1); gridLayout->setSpacing(4); gridLayout->setObjectName(QString::fromUtf8("gridLayout")); scrollArea->setWidget(scrollAreaWidgetContents1); tempVBoxLayout->addWidget(scrollArea); stackedWidget_2->addWidget(page); page_2 = new QWidget(); page_2->setObjectName(QString::fromUtf8("page_2")); tempVBoxLayout = new QVBoxLayout(page_2); QScrollArea *scrollArea2 = new QScrollArea(); scrollArea2->setObjectName(QString::fromUtf8("scrollArea2")); scrollArea2->setSizePolicy(sizePolicy); scrollArea2->setWidgetResizable(true); QWidget *scrollAreaWidgetContents2 = new QWidget(); scrollAreaWidgetContents2->setObjectName(QString::fromUtf8("scrollAreaWidgetContents2")); gridLayout2 = new QGridLayout(scrollAreaWidgetContents2); gridLayout2->setSpacing(4); gridLayout2->setObjectName(QString::fromUtf8("gridLayout2")); scrollArea2->setWidget(scrollAreaWidgetContents2); tempVBoxLayout->addWidget(scrollArea2); stackedWidget_2->addWidget(page_2); page_3 = new QWidget(); page_3->setObjectName(QString::fromUtf8("page_3")); tempVBoxLayout = new QVBoxLayout(page_3); QScrollArea *scrollArea3 = new QScrollArea(); scrollArea3->setObjectName(QString::fromUtf8("scrollArea3")); scrollArea3->setSizePolicy(sizePolicy); scrollArea3->setWidgetResizable(true); QWidget *scrollAreaWidgetContents3 = new QWidget(); scrollAreaWidgetContents3->setObjectName(QString::fromUtf8("scrollAreaWidgetContents3")); gridLayout3 = new QGridLayout(scrollAreaWidgetContents3); gridLayout3->setSpacing(4); gridLayout3->setObjectName(QString::fromUtf8("gridLayout3")); scrollArea3->setWidget(scrollAreaWidgetContents3); tempVBoxLayout->addWidget(scrollArea3); stackedWidget_2->addWidget(page_3); page_4 = new QWidget(); page_4->setObjectName(QString::fromUtf8("page_4")); tempVBoxLayout = new QVBoxLayout(page_4); QScrollArea *scrollArea4 = new QScrollArea(); scrollArea4->setObjectName(QString::fromUtf8("scrollArea4")); scrollArea4->setSizePolicy(sizePolicy); scrollArea4->setWidgetResizable(true); QWidget *scrollAreaWidgetContents4 = new QWidget(); scrollAreaWidgetContents4->setObjectName(QString::fromUtf8("scrollAreaWidgetContents4")); gridLayout4 = new QGridLayout(scrollAreaWidgetContents4); gridLayout4->setSpacing(4); gridLayout4->setObjectName(QString::fromUtf8("gridLayout4")); scrollArea4->setWidget(scrollAreaWidgetContents4); tempVBoxLayout->addWidget(scrollArea4); stackedWidget_2->addWidget(page_4); page_5 = new QWidget(); page_5->setObjectName(QString::fromUtf8("page_5")); tempVBoxLayout = new QVBoxLayout(page_5); QScrollArea *scrollArea5 = new QScrollArea(); scrollArea5->setObjectName(QString::fromUtf8("scrollArea5")); scrollArea5->setSizePolicy(sizePolicy); scrollArea5->setWidgetResizable(true); QWidget *scrollAreaWidgetContents5 = new QWidget(); scrollAreaWidgetContents5->setObjectName(QString::fromUtf8("scrollAreaWidgetContents5")); gridLayout5 = new QGridLayout(scrollAreaWidgetContents5); gridLayout5->setSpacing(4); gridLayout5->setObjectName(QString::fromUtf8("gridLayout5")); scrollArea5->setWidget(scrollAreaWidgetContents5); tempVBoxLayout->addWidget(scrollArea5); stackedWidget_2->addWidget(page_5); page_6 = new QWidget(); page_6->setObjectName(QString::fromUtf8("page_6")); tempVBoxLayout = new QVBoxLayout(page_6); QScrollArea *scrollArea6 = new QScrollArea(); scrollArea6->setObjectName(QString::fromUtf8("scrollArea6")); scrollArea6->setSizePolicy(sizePolicy); scrollArea6->setWidgetResizable(true); QWidget *scrollAreaWidgetContents6 = new QWidget(); scrollAreaWidgetContents6->setObjectName(QString::fromUtf8("scrollAreaWidgetContents6")); gridLayout6 = new QGridLayout(scrollAreaWidgetContents6); gridLayout6->setSpacing(4); gridLayout6->setObjectName(QString::fromUtf8("gridLayout6")); scrollArea6->setWidget(scrollAreaWidgetContents6); tempVBoxLayout->addWidget(scrollArea6); stackedWidget_2->addWidget(page_6); page_7 = new QWidget(); page_7->setObjectName(QString::fromUtf8("page_7")); tempVBoxLayout = new QVBoxLayout(page_7); QScrollArea *scrollArea7 = new QScrollArea(); scrollArea7->setObjectName(QString::fromUtf8("scrollArea7")); scrollArea7->setSizePolicy(sizePolicy); scrollArea7->setWidgetResizable(true); QWidget *scrollAreaWidgetContents7 = new QWidget(); scrollAreaWidgetContents7->setObjectName(QString::fromUtf8("scrollAreaWidgetContents7")); gridLayout7 = new QGridLayout(scrollAreaWidgetContents7); gridLayout7->setSpacing(4); gridLayout7->setObjectName(QString::fromUtf8("gridLayout7")); scrollArea7->setWidget(scrollAreaWidgetContents7); tempVBoxLayout->addWidget(scrollArea7); stackedWidget_2->addWidget(page_7); page_8 = new QWidget(); page_8->setObjectName(QString::fromUtf8("page_8")); tempVBoxLayout = new QVBoxLayout(page_8); QScrollArea *scrollArea8 = new QScrollArea(); scrollArea8->setObjectName(QString::fromUtf8("scrollArea8")); scrollArea8->setSizePolicy(sizePolicy); scrollArea8->setWidgetResizable(true); QWidget *scrollAreaWidgetContents8 = new QWidget(); scrollAreaWidgetContents8->setObjectName(QString::fromUtf8("scrollAreaWidgetContents8")); gridLayout8 = new QGridLayout(scrollAreaWidgetContents8); gridLayout8->setSpacing(4); gridLayout8->setObjectName(QString::fromUtf8("gridLayout8")); scrollArea8->setWidget(scrollAreaWidgetContents8); tempVBoxLayout->addWidget(scrollArea8); stackedWidget_2->addWidget(page_8); verticalLayout->addWidget(stackedWidget_2); verticalSpacer_3 = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Fixed); verticalLayout->addItem(verticalSpacer_3); horizontalLayout_2 = new QHBoxLayout(); horizontalLayout_2->setSpacing(6); horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); setsMenuButton = new QPushButton(tr("Sets"), this); QMenu *setMenu = new QMenu(setsMenuButton); copySetMenu = new QMenu(tr("Copy from Set"), setMenu); QAction *setSettingsAction = new QAction(tr("Settings"), setMenu); connect(setSettingsAction, &QAction::triggered, this, &JoyTabWidget::showSetNamesDialog); setMenu->addAction(setSettingsAction); setMenu->addMenu(copySetMenu); setMenu->addSeparator(); refreshCopySetActions(); setAction1 = new QAction(tr("Set 1"), setMenu); connect(setAction1, &QAction::triggered, this, &JoyTabWidget::changeSetOne); setMenu->addAction(setAction1); setAction2 = new QAction(tr("Set 2"), setMenu); connect(setAction2, &QAction::triggered, this, &JoyTabWidget::changeSetTwo); setMenu->addAction(setAction2); setAction3 = new QAction(tr("Set 3"), setMenu); connect(setAction3, &QAction::triggered, this, &JoyTabWidget::changeSetThree); setMenu->addAction(setAction3); setAction4 = new QAction(tr("Set 4"), setMenu); connect(setAction4, &QAction::triggered, this, &JoyTabWidget::changeSetFour); setMenu->addAction(setAction4); setAction5 = new QAction(tr("Set 5"), setMenu); connect(setAction5, &QAction::triggered, this, &JoyTabWidget::changeSetFive); setMenu->addAction(setAction5); setAction6 = new QAction(tr("Set 6"), setMenu); connect(setAction6, &QAction::triggered, this, &JoyTabWidget::changeSetSix); setMenu->addAction(setAction6); setAction7 = new QAction(tr("Set 7"), setMenu); connect(setAction7, &QAction::triggered, this, &JoyTabWidget::changeSetSeven); setMenu->addAction(setAction7); setAction8 = new QAction(tr("Set 8"), setMenu); connect(setAction8, &QAction::triggered, this, &JoyTabWidget::changeSetEight); setMenu->addAction(setAction8); setsMenuButton->setMenu(setMenu); horizontalLayout_2->addWidget(setsMenuButton); setPushButton1 = new QPushButton("1", this); setPushButton1->setObjectName(QString::fromUtf8("setPushButton1")); setPushButton1->setProperty("setActive", true); horizontalLayout_2->addWidget(setPushButton1); setPushButton2 = new QPushButton("2", this); setPushButton2->setObjectName(QString::fromUtf8("setPushButton2")); setPushButton2->setProperty("setActive", false); horizontalLayout_2->addWidget(setPushButton2); setPushButton3 = new QPushButton("3", this); setPushButton3->setObjectName(QString::fromUtf8("setPushButton3")); setPushButton3->setProperty("setActive", false); horizontalLayout_2->addWidget(setPushButton3); setPushButton4 = new QPushButton("4", this); setPushButton4->setObjectName(QString::fromUtf8("setPushButton4")); setPushButton4->setProperty("setActive", false); horizontalLayout_2->addWidget(setPushButton4); setPushButton5 = new QPushButton("5", this); setPushButton5->setObjectName(QString::fromUtf8("setPushButton5")); setPushButton5->setProperty("setActive", false); horizontalLayout_2->addWidget(setPushButton5); setPushButton6 = new QPushButton("6", this); setPushButton6->setObjectName(QString::fromUtf8("setPushButton6")); setPushButton6->setProperty("setActive", false); horizontalLayout_2->addWidget(setPushButton6); setPushButton7 = new QPushButton("7", this); setPushButton7->setObjectName(QString::fromUtf8("setPushButton7")); setPushButton7->setProperty("setActive", false); horizontalLayout_2->addWidget(setPushButton7); setPushButton8 = new QPushButton("8", this); setPushButton8->setObjectName(QString::fromUtf8("setPushButton8")); setPushButton8->setProperty("setActive", false); horizontalLayout_2->addWidget(setPushButton8); refreshSetButtons(); verticalLayout->addLayout(horizontalLayout_2); spacer3 = new QSpacerItem(20, 5, QSizePolicy::Fixed, QSizePolicy::Fixed); verticalLayout->addItem(spacer3); horizontalLayout_3 = new QHBoxLayout(); horizontalLayout_3->setSpacing(6); horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3")); stickAssignPushButton = new QPushButton(tr("Stick/Pad Assign"), this); stickAssignPushButton->setObjectName(QString::fromUtf8("stickAssignPushButton")); QIcon icon7( QIcon::fromTheme(QString::fromUtf8("games_config_options"), QIcon(":/images/actions/games_config_options.png"))); stickAssignPushButton->setIcon(icon7); horizontalLayout_3->addWidget(stickAssignPushButton); gameControllerMappingPushButton = new QPushButton(tr("Controller Mapping"), this); gameControllerMappingPushButton->setObjectName(QString::fromUtf8("gameControllerMappingPushButton")); gameControllerMappingPushButton->setIcon( QIcon::fromTheme(QString::fromUtf8("games_config_options"), QIcon(":/images/actions/games_config_options.png"))); gameControllerMappingPushButton->setEnabled(false); gameControllerMappingPushButton->setVisible(false); horizontalLayout_3->addWidget(gameControllerMappingPushButton); quickSetPushButton = new QPushButton(tr("Quick Set"), this); quickSetPushButton->setObjectName(QString::fromUtf8("quickSetPushButton")); horizontalLayout_3->addWidget(quickSetPushButton); QSpacerItem *horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout_3->addItem(horizontalSpacer_2); namesPushButton = new QPushButton(tr("Names"), this); namesPushButton->setObjectName(QString::fromUtf8("namesPushButton")); namesPushButton->setToolTip(tr("Toggle button name displaying.")); namesPushButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); namesPushButton->setIcon(QIcon::fromTheme(QString::fromUtf8("text_field"), QIcon(":/images/actions/text_field.png"))); horizontalLayout_3->addWidget(namesPushButton); delayButton = new QPushButton(tr("Pref"), this); delayButton->setObjectName(QString::fromUtf8("delayButton")); delayButton->setToolTip(tr("Change global profile settings.")); delayButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); horizontalLayout_3->addWidget(delayButton); resetButton = new QPushButton(tr("Reset"), this); resetButton->setObjectName(QString::fromUtf8("resetButton")); resetButton->setToolTip(tr("Revert changes to the configuration. Reload configuration file.")); resetButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); resetButton->setIcon(PadderCommon::loadIcon("document-revert", ":/images/actions/document_revert.png")); horizontalLayout_3->addWidget(resetButton); verticalLayout->addLayout(horizontalLayout_3); displayingNames = false; stickAssignPushButton->setEnabled(false); stickAssignPushButton->setVisible(false); gameControllerMappingPushButton->setEnabled(true); gameControllerMappingPushButton->setVisible(true); checkHideEmptyOption(); connect(loadButton, &QPushButton::clicked, this, &JoyTabWidget::openConfigFileDialog); connect(saveButton, &QPushButton::clicked, this, &JoyTabWidget::saveConfigFile); connect(resetButton, &QPushButton::clicked, this, &JoyTabWidget::resetJoystick); connect(namesPushButton, &QPushButton::clicked, this, &JoyTabWidget::toggleNames); connect(saveAsButton, &QPushButton::clicked, this, &JoyTabWidget::saveAsConfig); connect(delayButton, &QPushButton::clicked, this, &JoyTabWidget::showKeyDelayDialog); connect(removeButton, &QPushButton::clicked, this, &JoyTabWidget::removeConfig); connect(setPushButton1, &QPushButton::clicked, this, &JoyTabWidget::changeSetOne); connect(setPushButton2, &QPushButton::clicked, this, &JoyTabWidget::changeSetTwo); connect(setPushButton3, &QPushButton::clicked, this, &JoyTabWidget::changeSetThree); connect(setPushButton4, &QPushButton::clicked, this, &JoyTabWidget::changeSetFour); connect(setPushButton5, &QPushButton::clicked, this, &JoyTabWidget::changeSetFive); connect(setPushButton6, &QPushButton::clicked, this, &JoyTabWidget::changeSetSix); connect(setPushButton7, &QPushButton::clicked, this, &JoyTabWidget::changeSetSeven); connect(setPushButton8, &QPushButton::clicked, this, &JoyTabWidget::changeSetEight); connect(stickAssignPushButton, &QPushButton::clicked, this, &JoyTabWidget::showStickAssignmentDialog); connect(gameControllerMappingPushButton, &QPushButton::clicked, this, &JoyTabWidget::openGameControllerMappingWindow); connect(quickSetPushButton, &QPushButton::clicked, this, &JoyTabWidget::showQuickSetDialog); connect(this, &JoyTabWidget::joystickConfigChanged, this, &JoyTabWidget::refreshSetButtons); connect(this, &JoyTabWidget::joystickConfigChanged, this, &JoyTabWidget::refreshCopySetActions); connect(joystick, &InputDevice::profileUpdated, this, &JoyTabWidget::displayProfileEditNotification); connect(joystick, &InputDevice::requestProfileLoad, this, &JoyTabWidget::loadConfigFile, Qt::QueuedConnection); reconnectCheckUnsavedEvent(); reconnectMainComboBoxEvents(); } bool JoyTabWidget::isKeypadUnlocked() { if (m_settings == nullptr) return false; return m_settings->value("AttachNumKeypad", false).toBool(); } void JoyTabWidget::openConfigFileDialog() { m_settings->getLock()->lock(); int numberRecentProfiles = m_settings->value("NumberRecentProfiles", DEFAULTNUMBERPROFILES).toInt(); QString lookupDir = PadderCommon::preferredProfileDir(m_settings); QString filename = QFileDialog::getOpenFileName(this, tr("Open Config"), lookupDir, tr("Config Files (*.amgp *.xml)")); m_settings->getLock()->unlock(); if (!filename.isNull() && !filename.isEmpty()) { QFileInfo fileinfo(filename); int searchIndex = configBox->findData(fileinfo.absoluteFilePath()); if (searchIndex == -1) { if ((numberRecentProfiles > 0) && (configBox->count() == (numberRecentProfiles + 1))) { configBox->removeItem(numberRecentProfiles); } configBox->insertItem(1, PadderCommon::getProfileName(fileinfo), fileinfo.absoluteFilePath()); configBox->setCurrentIndex(1); saveDeviceSettings(); emit joystickConfigChanged(m_joystick->getJoyNumber()); } else { configBox->setCurrentIndex(searchIndex); saveDeviceSettings(); emit joystickConfigChanged(m_joystick->getJoyNumber()); } QString outputFilename = fileinfo.absoluteDir().absolutePath(); #if defined(Q_OS_WIN) && defined(WIN_PORTABLE_PACKAGE) if (fileinfo.absoluteDir().isAbsolute()) { QDir tempDir = fileinfo.dir(); tempDir.cdUp(); if (tempDir.path() == qApp->applicationDirPath()) { outputFilename = QString("%1/").arg(fileinfo.dir().dirName()); } } #endif m_settings->getLock()->lock(); m_settings->setValue("LastProfileDir", outputFilename); m_settings->sync(); m_settings->getLock()->unlock(); } } /** * @brief Create and render all push buttons corresponding to joystick * controls for all sets. */ void JoyTabWidget::fillButtons() { m_joystick->establishPropertyUpdatedConnection(); connect(m_joystick, &InputDevice::setChangeActivated, this, &JoyTabWidget::changeCurrentSet, Qt::QueuedConnection); for (int i = 0; i < GlobalVariables::InputDevice::NUMBER_JOYSETS; i++) { SetJoystick *currentSet = m_joystick->getSetJoystick(i); fillSetButtons(currentSet); } refreshCopySetActions(); } void JoyTabWidget::showButtonDialog() { JoyButtonWidget *buttonWidget = qobject_cast(sender()); // static_cast JoyButton *button = buttonWidget->getJoyButton(); for (auto eachAssigned : *button->getAssignedSlots()) { qDebug() << "eachAssigned slot mode: " << eachAssigned->getSlotMode(); if (eachAssigned->getSlotMode() == 15) { qDebug() << "text data is: " << eachAssigned->getTextData(); } } ButtonEditDialog *dialog = new ButtonEditDialog(button, m_joystick, isKeypadUnlocked(), this); dialog->show(); } void JoyTabWidget::showAxisDialog() { JoyAxisWidget *axisWidget = qobject_cast(sender()); // static_cast JoyAxis *axis = axisWidget->getAxis(); axisDialog = new AxisEditDialog(axis, isKeypadUnlocked(), this); axisDialog->show(); } void JoyTabWidget::saveConfigFile() { int index = configBox->currentIndex(); m_settings->getLock()->lock(); int numberRecentProfiles = m_settings->value("NumberRecentProfiles", DEFAULTNUMBERPROFILES).toInt(); QString filename = QString(); if (index == 0) { QString lookupDir = PadderCommon::preferredProfileDir(m_settings); m_settings->getLock()->unlock(); QString tempfilename = QFileDialog::getSaveFileName(this, tr("Save Config"), lookupDir, tr("Config File (*.%1.amgp)").arg(m_joystick->getXmlName())); if (!tempfilename.isEmpty()) { filename = tempfilename; QFileInfo fileinfo(filename); QString deviceTypeName = m_joystick->getXmlName(); QString fileSuffix = deviceTypeName.append(".amgp"); if ((fileinfo.suffix() != "xml") && (fileinfo.suffix() != "amgp")) { filename = filename.append(".").append(fileSuffix); } } } else { m_settings->getLock()->unlock(); filename = configBox->itemData(index).toString(); } if (!filename.isEmpty()) { QFileInfo fileinfo(filename); QMetaObject::invokeMethod(&tabHelper, "writeConfigFile", Qt::BlockingQueuedConnection, Q_ARG(QString, fileinfo.absoluteFilePath())); XMLConfigWriter *writer = tabHelper.getWriter(); if (writer->hasError() && this->window()->isEnabled()) { QMessageBox msg; msg.setStandardButtons(QMessageBox::Close); msg.setText(writer->getErrorString()); msg.setModal(true); msg.exec(); } else if (writer->hasError() && !this->window()->isEnabled()) { PRINT_STDERR() << writer->getErrorString() << "\n"; } else { int existingIndex = configBox->findData(fileinfo.absoluteFilePath()); if (existingIndex == -1) { if ((numberRecentProfiles > 0) && (configBox->count() == (numberRecentProfiles + 1))) { configBox->removeItem(numberRecentProfiles); } m_joystick->revertProfileEdited(); QString tempProfileName = PadderCommon::getProfileName(fileinfo); if (!m_joystick->getProfileName().isEmpty()) { oldProfileName = m_joystick->getProfileName(); tempProfileName = oldProfileName; } disconnectCheckUnsavedEvent(); disconnectMainComboBoxEvents(); configBox->insertItem(1, tempProfileName, fileinfo.absoluteFilePath()); reconnectCheckUnsavedEvent(); reconnectMainComboBoxEvents(); configBox->setCurrentIndex(1); saveDeviceSettings(true); emit joystickConfigChanged(m_joystick->getJoyNumber()); } else { m_joystick->revertProfileEdited(); if (!m_joystick->getProfileName().isEmpty()) { oldProfileName = m_joystick->getProfileName(); } configBox->setItemIcon(existingIndex, QIcon()); saveDeviceSettings(true); emit joystickConfigChanged(m_joystick->getJoyNumber()); } } } } void JoyTabWidget::resetJoystick() { QMessageBox msg; msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msg.setText(tr("Do you really want to reset buttons settings for joystick?")); int result = msg.exec(); if (result == QMessageBox::Yes) { int currentIndex = configBox->currentIndex(); if (currentIndex != 0) { removeCurrentButtons(); QMetaObject::invokeMethod(&tabHelper, "reInitDevice", Qt::BlockingQueuedConnection); fillButtons(); refreshSetButtons(); refreshCopySetActions(); XMLConfigReader *reader = tabHelper.getReader(); if (!reader->hasError()) { configBox->setItemIcon(currentIndex, QIcon()); QString tempProfileName = QString(); if (!m_joystick->getProfileName().isEmpty()) { tempProfileName = m_joystick->getProfileName(); configBox->setItemText(currentIndex, tempProfileName); } else { tempProfileName = oldProfileName; configBox->setItemText(currentIndex, oldProfileName); } oldProfileName = tempProfileName; } else if (reader->hasError() && this->window()->isEnabled()) { QMessageBox msg; msg.setStandardButtons(QMessageBox::Close); msg.setText(reader->getErrorString()); msg.setModal(true); msg.exec(); } else if (reader->hasError() && !this->window()->isEnabled()) { PRINT_STDERR() << reader->getErrorString() << "\n"; } displayProfileEditNotification(); } else { configBox->setItemText(0, tr("")); configBox->setItemIcon(0, QIcon()); removeCurrentButtons(); QMetaObject::invokeMethod(&tabHelper, "reInitDevice", Qt::BlockingQueuedConnection); fillButtons(); refreshSetButtons(); refreshCopySetActions(); } } } void JoyTabWidget::saveAsConfig() { int index = configBox->currentIndex(); m_settings->getLock()->lock(); int numberRecentProfiles = m_settings->value("NumberRecentProfiles", DEFAULTNUMBERPROFILES).toInt(); QString filename = QString(); if (index == 0) { QString lookupDir = PadderCommon::preferredProfileDir(m_settings); m_settings->getLock()->unlock(); QString tempfilename = QFileDialog::getSaveFileName(this, tr("Save Config"), lookupDir, tr("Config File (*.%1.amgp)").arg(m_joystick->getXmlName())); if (!tempfilename.isEmpty()) { filename = tempfilename; } } else { m_settings->getLock()->unlock(); QString configPath = configBox->itemData(index).toString(); QFileInfo temp(configPath); QString tempfilename = QFileDialog::getSaveFileName(this, tr("Save Config"), temp.absoluteDir().absolutePath(), tr("Config File (*.%1.amgp)").arg(m_joystick->getXmlName())); if (!tempfilename.isEmpty()) { filename = tempfilename; } } if (!filename.isEmpty()) { QFileInfo fileinfo(filename); QString deviceTypeName = m_joystick->getXmlName(); QString fileSuffix = deviceTypeName.append(".amgp"); if ((fileinfo.suffix() != "xml") && (fileinfo.suffix() != "amgp")) { filename = filename.append(".").append(fileSuffix); } fileinfo.setFile(filename); QMetaObject::invokeMethod(&tabHelper, "writeConfigFile", Qt::BlockingQueuedConnection, Q_ARG(QString, fileinfo.absoluteFilePath())); XMLConfigWriter *writer = tabHelper.getWriter(); if (writer->hasError() && this->window()->isEnabled()) { QMessageBox msg; msg.setStandardButtons(QMessageBox::Close); msg.setText(writer->getErrorString()); msg.setModal(true); msg.exec(); } else if (writer->hasError() && !this->window()->isEnabled()) { PRINT_STDERR() << writer->getErrorString() << "\n"; } else { int existingIndex = configBox->findData(fileinfo.absoluteFilePath()); if (existingIndex == -1) { disconnectCheckUnsavedEvent(); disconnectMainComboBoxEvents(); if ((numberRecentProfiles > 0) && (configBox->count() == (numberRecentProfiles + 1))) { configBox->removeItem(numberRecentProfiles); } m_joystick->revertProfileEdited(); QString tempProfileName = PadderCommon::getProfileName(fileinfo); if (!m_joystick->getProfileName().isEmpty()) { oldProfileName = m_joystick->getProfileName(); tempProfileName = oldProfileName; } configBox->insertItem(1, tempProfileName, fileinfo.absoluteFilePath()); reconnectCheckUnsavedEvent(); reconnectMainComboBoxEvents(); configBox->setCurrentIndex(1); saveDeviceSettings(true); emit joystickConfigChanged(m_joystick->getJoyNumber()); } else { m_joystick->revertProfileEdited(); if (!m_joystick->getProfileName().isEmpty()) { oldProfileName = m_joystick->getProfileName(); } configBox->setItemIcon(existingIndex, QIcon()); saveDeviceSettings(true); emit joystickConfigChanged(m_joystick->getJoyNumber()); } } } } void JoyTabWidget::changeJoyConfig(int index) { disconnect(m_joystick, &InputDevice::profileUpdated, this, &JoyTabWidget::displayProfileEditNotification); QString filename = QString(); if (index > 0) { filename = configBox->itemData(index).toString(); qInfo() << "Change joystick " << m_joystick->getSDLName() << " profile to: " << filename; } if (!filename.isEmpty()) { removeCurrentButtons(); emit forceTabUnflash(this); qDebug() << "SDL Current Power Level: " << SDL_JoystickCurrentPowerLevel(m_joystick->getJoyHandle()) << "\n"; if (SDL_JoystickCurrentPowerLevel(m_joystick->getJoyHandle()) == SDL_JOYSTICK_POWER_WIRED || SDL_JoystickCurrentPowerLevel(m_joystick->getJoyHandle()) == SDL_JOYSTICK_POWER_UNKNOWN) { QMetaObject::invokeMethod(&tabHelper, "readConfigFile", Qt::BlockingQueuedConnection, Q_ARG(QString, filename)); } else { tabHelper.readConfigFile(filename); } fillButtons(); refreshSetButtons(); refreshCopySetActions(); configBox->setItemText(0, tr("")); XMLConfigReader *reader = tabHelper.getReader(); if (!reader->hasError()) { QString profileName = QString(); if (!m_joystick->getProfileName().isEmpty()) { profileName = m_joystick->getProfileName(); oldProfileName = profileName; } else { QFileInfo profile(filename); oldProfileName = PadderCommon::getProfileName(profile); profileName = oldProfileName; } configBox->setItemText(index, profileName); } else if (reader->hasError() && this->window()->isEnabled()) { QMessageBox msg; msg.setStandardButtons(QMessageBox::Close); msg.setText(reader->getErrorString()); msg.setModal(true); msg.exec(); } else if (reader->hasError() && !this->window()->isEnabled()) { PRINT_STDERR() << reader->getErrorString() << "\n"; } } else if (index == 0) { removeCurrentButtons(); emit forceTabUnflash(this); QMetaObject::invokeMethod(&tabHelper, "reInitDevice", Qt::BlockingQueuedConnection); fillButtons(); refreshSetButtons(); refreshCopySetActions(); configBox->setItemText(0, tr("")); oldProfileName = ""; } comboBoxIndex = index; connect(m_joystick, &InputDevice::profileUpdated, this, &JoyTabWidget::displayProfileEditNotification); } void JoyTabWidget::saveSettings() { qInfo() << "Saving config settings: " << configBox->currentText() << " for controller: " << m_joystick->getSDLName(); QString filename = ""; QString lastfile = ""; m_settings->getLock()->lock(); int index = configBox->currentIndex(); int currentjoy = 1; QString identifier = m_joystick->getStringIdentifier(); QString controlEntryPrefix = QString("Controller%1").arg(identifier); QString controlEntryString = QString("Controller%1ConfigFile%2").arg(identifier); QString controlEntryLastSelected = QString("Controller%1LastSelected").arg(identifier); QString controlEntryProfileName = QString("Controller%1ProfileName%2").arg(m_joystick->getStringIdentifier()); // Remove current settings for a controller QStringList tempkeys = m_settings->allKeys(); for (auto &&tempstring : tempkeys) { // QString tempstring = iter.next(); if (!identifier.isEmpty() && tempstring.startsWith(controlEntryPrefix)) { m_settings->remove(tempstring); } } // Output currently selected profile as first profile on the list if (index != 0) { filename = lastfile = configBox->itemData(index).toString(); QString profileText = configBox->itemText(index); if (!identifier.isEmpty()) { QFileInfo profileBaseFile(filename); QString outputFilename = filename; #if defined(Q_OS_WIN) && defined(WIN_PORTABLE_PACKAGE) if (profileBaseFile.isAbsolute()) { QDir tempDir = profileBaseFile.dir(); tempDir.cdUp(); if (tempDir.path() == qApp->applicationDirPath()) { outputFilename = QString("%1/%2").arg(profileBaseFile.dir().dirName()).arg(profileBaseFile.fileName()); } } #endif m_settings->setValue(controlEntryString.arg(currentjoy), outputFilename); if (PadderCommon::getProfileName(profileBaseFile) != profileText) { m_settings->setValue(controlEntryProfileName.arg(currentjoy), profileText); } } currentjoy++; } else { lastfile = ""; } // Write the remaining profile locations to the settings file for (int i = 1; i < configBox->count(); i++) { if (i != index) { filename = configBox->itemData(i).toString(); QString profileText = configBox->itemText(i); if (!identifier.isEmpty()) { QFileInfo profileBaseFile(filename); QString outputFilename = filename; #if defined(Q_OS_WIN) && defined(WIN_PORTABLE_PACKAGE) if (profileBaseFile.isAbsolute()) { QDir tempDir = profileBaseFile.dir(); tempDir.cdUp(); if (tempDir.path() == qApp->applicationDirPath()) { outputFilename = QString("%1/%2").arg(profileBaseFile.dir().dirName()).arg(profileBaseFile.fileName()); } } #endif m_settings->setValue(controlEntryString.arg(currentjoy), outputFilename); if (PadderCommon::getProfileName(profileBaseFile) != profileText) { m_settings->setValue(controlEntryProfileName.arg(currentjoy), profileText); } } currentjoy++; } } if (!identifier.isEmpty()) { QFileInfo profileBaseFile(lastfile); QString outputFilename = lastfile; #if defined(Q_OS_WIN) && defined(WIN_PORTABLE_PACKAGE) if (profileBaseFile.isAbsolute()) { QDir tempDir = profileBaseFile.dir(); tempDir.cdUp(); if (tempDir.path() == qApp->applicationDirPath()) { outputFilename = QString("%1/%2").arg(profileBaseFile.dir().dirName()).arg(profileBaseFile.fileName()); } } #endif m_settings->setValue(controlEntryLastSelected, outputFilename); } m_settings->getLock()->unlock(); } void JoyTabWidget::loadSettings(bool forceRefresh) { qInfo() << "Loading device settings for: " << m_joystick->getSDLName(); disconnect(configBox, static_cast(&QComboBox::currentIndexChanged), this, &JoyTabWidget::changeJoyConfig); m_settings->getLock()->lock(); if (configBox->count() > 1) { configBox->clear(); configBox->addItem(tr(""), ""); configBox->setCurrentIndex(-1); } else if (forceRefresh) { configBox->setCurrentIndex(-1); } int shouldisplaynames = m_settings->value("DisplayNames", "0").toInt(); if (shouldisplaynames == 1) { changeNameDisplay(shouldisplaynames); } int numberRecentProfiles = m_settings->value("NumberRecentProfiles", DEFAULTNUMBERPROFILES).toInt(); bool autoOpenLastProfile = m_settings->value("AutoOpenLastProfile", true).toBool(); m_settings->beginGroup("Controllers"); convToUniqueIDControllerGroupSett(m_settings, QString("Controller%1LastSelected").arg(m_joystick->getGUIDString()), QString("Controller%1LastSelected").arg(m_joystick->getUniqueIDString())); QString controlEntryString = QString("Controller%1ConfigFile%2").arg(m_joystick->getStringIdentifier()); QString controlEntryLastSelected = QString("Controller%1LastSelected").arg(m_joystick->getStringIdentifier()); QString controlEntryProfileName = QString("Controller%1ProfileName%2").arg(m_joystick->getStringIdentifier()); bool finished = false; for (int configFileNum = 1; !finished; configFileNum++) { QString tempfilepath = QString(); if (!m_joystick->getStringIdentifier().isEmpty()) { convToUniqueIDControllerGroupSett( m_settings, QString("Controller%1ConfigFile%2").arg(m_joystick->getGUIDString()).arg(configFileNum), QString("Controller%1ConfigFile%2").arg(m_joystick->getUniqueIDString()).arg(configFileNum)); tempfilepath = m_settings->value(controlEntryString.arg(configFileNum), "").toString(); } if (!tempfilepath.isEmpty()) { QFileInfo fileInfo(tempfilepath); if (fileInfo.exists() && (configBox->findData(fileInfo.absoluteFilePath()) == -1)) { convToUniqueIDControllerGroupSett( m_settings, QString("Controller%1ProfileName%2").arg(m_joystick->getGUIDString()).arg(configFileNum), QString("Controller%1ProfileName%2").arg(m_joystick->getUniqueIDString()).arg(configFileNum)); QString profileName = m_settings->value(controlEntryProfileName.arg(configFileNum), "").toString(); profileName = !profileName.isEmpty() ? profileName : PadderCommon::getProfileName(fileInfo); configBox->addItem(profileName, fileInfo.absoluteFilePath()); } } else { finished = true; } if ((numberRecentProfiles > 0) && (configFileNum == numberRecentProfiles)) { finished = true; } } connect(configBox, static_cast(&QComboBox::currentIndexChanged), this, &JoyTabWidget::changeJoyConfig, Qt::QueuedConnection); QString lastfile = QString(); if (!m_joystick->getStringIdentifier().isEmpty() && autoOpenLastProfile) { lastfile = m_settings->value(controlEntryLastSelected, "").toString(); } m_settings->endGroup(); m_settings->getLock()->unlock(); if (!lastfile.isEmpty()) { QString lastFileAbsolute = lastfile; #if defined(Q_OS_WIN) && defined(WIN_PORTABLE_PACKAGE) QFileInfo lastFileInfo(lastfile); lastFileAbsolute = lastFileInfo.absoluteFilePath(); #endif int lastindex = configBox->findData(lastFileAbsolute); if (lastindex > 0) { configBox->setCurrentIndex(lastindex); emit joystickConfigChanged(m_joystick->getJoyNumber()); } else if (configBox->currentIndex() != 0) { configBox->setCurrentIndex(0); emit joystickConfigChanged(m_joystick->getJoyNumber()); } } else if (configBox->currentIndex() != 0) { configBox->setCurrentIndex(0); emit joystickConfigChanged(m_joystick->getJoyNumber()); } } QHash *JoyTabWidget::recentConfigs() { QHash *temp = new QHash(); for (int i = 1; i < configBox->count(); i++) { QString current = configBox->itemText(i); temp->insert(i, current); } return temp; } void JoyTabWidget::setCurrentConfig(int index) { // Allow 0 to select new/'null' config and therefore disable any mapping if ((index >= 0) && (index < configBox->count())) { configBox->setCurrentIndex(index); } } int JoyTabWidget::getCurrentConfigIndex() { return configBox->currentIndex(); } QString JoyTabWidget::getCurrentConfigName() { return configBox->currentText(); } QString JoyTabWidget::getConfigName(int index) { return configBox->itemText(index); } // Switch widget to currently selected Set void JoyTabWidget::changeCurrentSet(int index) { int currentPage = stackedWidget_2->currentIndex(); QPushButton *oldSetButton = nullptr; QPushButton *activeSetButton = nullptr; switch (currentPage) { case 0: oldSetButton = setPushButton1; break; case 1: oldSetButton = setPushButton2; break; case 2: oldSetButton = setPushButton3; break; case 3: oldSetButton = setPushButton4; break; case 4: oldSetButton = setPushButton5; break; case 5: oldSetButton = setPushButton6; break; case 6: oldSetButton = setPushButton7; break; case 7: oldSetButton = setPushButton8; break; default: break; } if (oldSetButton != nullptr) { oldSetButton->setProperty("setActive", false); oldSetButton->style()->unpolish(oldSetButton); oldSetButton->style()->polish(oldSetButton); } stackedWidget_2->setCurrentIndex(index); switch (index) { case 0: activeSetButton = setPushButton1; break; case 1: activeSetButton = setPushButton2; break; case 2: activeSetButton = setPushButton3; break; case 3: activeSetButton = setPushButton4; break; case 4: activeSetButton = setPushButton5; break; case 5: activeSetButton = setPushButton6; break; case 6: activeSetButton = setPushButton7; break; case 7: activeSetButton = setPushButton8; break; default: break; } if (activeSetButton != nullptr) { activeSetButton->setProperty("setActive", true); activeSetButton->style()->unpolish(activeSetButton); activeSetButton->style()->polish(activeSetButton); } } void JoyTabWidget::changeSetOne() { m_joystick->setActiveSetNumber(0); changeCurrentSet(0); } void JoyTabWidget::changeSetTwo() { m_joystick->setActiveSetNumber(1); changeCurrentSet(1); } void JoyTabWidget::changeSetThree() { m_joystick->setActiveSetNumber(2); changeCurrentSet(2); } void JoyTabWidget::changeSetFour() { m_joystick->setActiveSetNumber(3); changeCurrentSet(3); } void JoyTabWidget::changeSetFive() { m_joystick->setActiveSetNumber(4); changeCurrentSet(4); } void JoyTabWidget::changeSetSix() { m_joystick->setActiveSetNumber(5); changeCurrentSet(5); } void JoyTabWidget::changeSetSeven() { m_joystick->setActiveSetNumber(6); changeCurrentSet(6); } void JoyTabWidget::changeSetEight() { m_joystick->setActiveSetNumber(7); changeCurrentSet(7); } void JoyTabWidget::showStickAssignmentDialog() { Joystick *temp = qobject_cast(m_joystick); // static_cast AdvanceStickAssignmentDialog *dialog = new AdvanceStickAssignmentDialog(temp, this); connect(dialog, &AdvanceStickAssignmentDialog::finished, this, &JoyTabWidget::refreshButtons); dialog->show(); } void JoyTabWidget::loadConfigFile(QString fileLocation) { checkForUnsavedProfile(-1); if (!m_joystick->isDeviceEdited()) { int numberRecentProfiles = m_settings->value("NumberRecentProfiles", DEFAULTNUMBERPROFILES).toInt(); QFileInfo fileinfo(fileLocation); if (fileinfo.exists() && ((fileinfo.suffix() == "xml") || (fileinfo.suffix() == "amgp"))) { qDebug() << "Loading config file: " << fileLocation; int searchIndex = configBox->findData(fileinfo.absoluteFilePath()); if (searchIndex == -1) { disconnectCheckUnsavedEvent(); disconnectMainComboBoxEvents(); if ((numberRecentProfiles > 0) && (configBox->count() == (numberRecentProfiles + 1))) { configBox->removeItem(numberRecentProfiles - 1); // configBox->removeItem(5); } configBox->insertItem(1, PadderCommon::getProfileName(fileinfo), fileinfo.absoluteFilePath()); reconnectCheckUnsavedEvent(); reconnectMainComboBoxEvents(); configBox->setCurrentIndex(1); emit joystickConfigChanged(m_joystick->getJoyNumber()); } else if (searchIndex != configBox->currentIndex()) { configBox->setCurrentIndex(searchIndex); emit joystickConfigChanged(m_joystick->getJoyNumber()); } qDebug() << "Config file loaded"; } } } void JoyTabWidget::showQuickSetDialog() { ButtonEditDialog *dialog = new ButtonEditDialog(m_joystick, isKeypadUnlocked(), this); connect(dialog, &ButtonEditDialog::finished, this, &JoyTabWidget::refreshButtons); dialog->show(); } void JoyTabWidget::showKeyDelayDialog() { ExtraProfileSettingsDialog *dialog = new ExtraProfileSettingsDialog(m_joystick, this); dialog->show(); } void JoyTabWidget::showSetNamesDialog() { SetNamesDialog *dialog = new SetNamesDialog(m_joystick, this); connect(dialog, &SetNamesDialog::accepted, this, &JoyTabWidget::refreshSetButtons); connect(dialog, &SetNamesDialog::accepted, this, &JoyTabWidget::refreshCopySetActions); dialog->show(); } void JoyTabWidget::removeCurrentButtons() { m_joystick->disconnectPropertyUpdatedConnection(); disconnect(m_joystick, &InputDevice::setChangeActivated, this, &JoyTabWidget::changeCurrentSet); for (int i = 0; i < GlobalVariables::InputDevice::NUMBER_JOYSETS; i++) { SetJoystick *currentSet = m_joystick->getSetJoystick(i); removeSetButtons(currentSet); } } InputDevice *JoyTabWidget::getJoystick() { return m_joystick; } void JoyTabWidget::removeConfig() { int currentIndex = configBox->currentIndex(); if (currentIndex > 0) { configBox->removeItem(currentIndex); saveDeviceSettings(true); emit joystickConfigChanged(m_joystick->getJoyNumber()); } } void JoyTabWidget::toggleNames() { displayingNames = !displayingNames; namesPushButton->setProperty("isDisplayingNames", displayingNames); namesPushButton->style()->unpolish(namesPushButton); namesPushButton->style()->polish(namesPushButton); emit namesDisplayChanged(displayingNames); } void JoyTabWidget::unloadConfig() { configBox->setCurrentIndex(0); } void JoyTabWidget::saveDeviceSettings(bool sync) { qInfo() << "Saving device settings."; m_settings->getLock()->lock(); m_settings->beginGroup("Controllers"); m_settings->getLock()->unlock(); saveSettings(); m_settings->getLock()->lock(); m_settings->endGroup(); if (sync) m_settings->sync(); m_settings->getLock()->unlock(); } void JoyTabWidget::loadDeviceSettings() { // m_settings->beginGroup("Controllers"); loadSettings(); // m_settings->endGroup(); } bool JoyTabWidget::isDisplayingNames() { return displayingNames; } void JoyTabWidget::changeNameDisplay(bool displayNames) { displayingNames = displayNames; namesPushButton->setProperty("isDisplayingNames", displayingNames); namesPushButton->style()->unpolish(namesPushButton); namesPushButton->style()->polish(namesPushButton); } void JoyTabWidget::refreshSetButtons() { for (int i = 0; i < GlobalVariables::InputDevice::NUMBER_JOYSETS; i++) { QPushButton *tempSetButton = nullptr; QAction *tempSetAction = nullptr; SetJoystick *tempSet = m_joystick->getSetJoystick(i); switch (i) { case 0: tempSetButton = setPushButton1; tempSetAction = setAction1; break; case 1: tempSetButton = setPushButton2; tempSetAction = setAction2; break; case 2: tempSetButton = setPushButton3; tempSetAction = setAction3; break; case 3: tempSetButton = setPushButton4; tempSetAction = setAction4; break; case 4: tempSetButton = setPushButton5; tempSetAction = setAction5; break; case 5: tempSetButton = setPushButton6; tempSetAction = setAction6; break; case 6: tempSetButton = setPushButton7; tempSetAction = setAction7; break; case 7: tempSetButton = setPushButton8; tempSetAction = setAction8; break; default: break; } if (!tempSet->getName().isEmpty()) { QString tempName = tempSet->getName(); QString tempNameEscaped = tempName; tempNameEscaped.replace("&", "&&"); tempSetButton->setText(tempNameEscaped); tempSetButton->setToolTip(tempName); tempSetAction->setText(tr("Set").append(" %1: %2").arg(i + 1).arg(tempNameEscaped)); } else { tempSetButton->setText(QString::number(i + 1)); tempSetButton->setToolTip(""); tempSetAction->setText(tr("Set").append(" %1").arg(i + 1)); } } } void JoyTabWidget::displayProfileEditNotification() { int currentIndex = configBox->currentIndex(); configBox->setItemIcon(currentIndex, PadderCommon::loadIcon("document-save-as", ":/images/actions/document_save_as.png")); changedNotSaved = true; } void JoyTabWidget::removeProfileEditNotification() { for (int i = 0; i < configBox->count(); i++) { if (!configBox->itemIcon(i).isNull()) { configBox->setItemIcon(i, QIcon()); } } changedNotSaved = false; } void JoyTabWidget::retranslateUi() { removeButton->setText(tr("Remove")); removeButton->setToolTip(tr("Remove configuration from recent list.")); loadButton->setText(tr("Load")); loadButton->setToolTip(tr("Load configuration file.")); saveButton->setText(tr("Save")); saveButton->setToolTip(tr("Save changes to configuration file.")); saveAsButton->setText(tr("Save As")); saveAsButton->setToolTip(tr("Save changes to a new configuration file.")); setsMenuButton->setText(tr("Sets")); setAction1->setText(tr("Set 1")); setAction2->setText(tr("Set 2")); setAction3->setText(tr("Set 3")); setAction4->setText(tr("Set 4")); setAction5->setText(tr("Set 5")); setAction6->setText(tr("Set 6")); setAction7->setText(tr("Set 7")); setAction8->setText(tr("Set 8")); refreshSetButtons(); refreshCopySetActions(); gameControllerMappingPushButton->setText(tr("Controller Mapping")); stickAssignPushButton->setText(tr("Stick/Pad Assign")); quickSetPushButton->setText(tr("Quick Set")); resetButton->setText(tr("Reset")); namesPushButton->setText(tr("Names")); namesPushButton->setToolTip(tr("Toggle button name displaying.")); delayButton->setText(tr("Pref")); delayButton->setToolTip(tr("Change global profile settings.")); resetButton->setText(tr("Reset")); resetButton->setToolTip(tr("Revert changes to the configuration. Reload configuration file.")); refreshButtons(); } void JoyTabWidget::checkForUnsavedProfile(int newindex) { if (m_joystick->isDeviceEdited()) { disconnectCheckUnsavedEvent(); disconnectMainComboBoxEvents(); if (configBox->currentIndex() != comboBoxIndex) { configBox->setCurrentIndex(comboBoxIndex); } QMessageBox msg; msg.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); msg.setWindowTitle(tr("Save Profile Changes?")); if (comboBoxIndex == 0) { msg.setText(tr( "Changes to the new profile have not been saved. Would you like to save or discard the current profile?")); } else { msg.setText(tr("Changes to the profile \"%1\" have not been saved. Would you like to save or discard changes to " "the current profile?") .arg(configBox->currentText())); } int status = msg.exec(); switch (status) { case QMessageBox::Save: { saveConfigFile(); reconnectCheckUnsavedEvent(); reconnectMainComboBoxEvents(); if (newindex > -1) { configBox->setCurrentIndex(newindex); } break; } case QMessageBox::Discard: { m_joystick->revertProfileEdited(); configBox->setItemText(comboBoxIndex, oldProfileName); reconnectCheckUnsavedEvent(); reconnectMainComboBoxEvents(); if (newindex > -1) { configBox->setCurrentIndex(newindex); } break; } case QMessageBox::Cancel: { reconnectCheckUnsavedEvent(); reconnectMainComboBoxEvents(); break; } } } } bool JoyTabWidget::discardUnsavedProfileChanges() { bool discarded = true; if (m_joystick->isDeviceEdited()) { disconnectCheckUnsavedEvent(); QMessageBox msg; msg.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); msg.setWindowTitle(tr("Save Profile Changes?")); int currentIndex = configBox->currentIndex(); if (currentIndex == 0) { msg.setText(tr( "Changes to the new profile have not been saved. Would you like to save or discard the current profile?")); } else { msg.setText(tr("Changes to the profile \"%1\" have not been saved. Would you like to save or discard changes to " "the current profile?") .arg(configBox->currentText())); } int status = msg.exec(); switch (status) { case QMessageBox::Save: { saveConfigFile(); if ((currentIndex == 0) && (currentIndex == configBox->currentIndex())) { discarded = false; } break; } case QMessageBox::Discard: { m_joystick->revertProfileEdited(); configBox->setItemText(currentIndex, oldProfileName); resetJoystick(); break; } case QMessageBox::Cancel: { discarded = false; break; } } disconnectMainComboBoxEvents(); reconnectCheckUnsavedEvent(); reconnectMainComboBoxEvents(); } return discarded; } bool JoyTabWidget::changesNotSaved() { return changedNotSaved; } void JoyTabWidget::disconnectMainComboBoxEvents() { disconnect(configBox, static_cast(&QComboBox::currentIndexChanged), this, &JoyTabWidget::changeJoyConfig); disconnect(configBox, static_cast(&QComboBox::currentIndexChanged), this, &JoyTabWidget::removeProfileEditNotification); disconnect(m_joystick, &InputDevice::profileNameEdited, this, &JoyTabWidget::editCurrentProfileItemText); } void JoyTabWidget::reconnectMainComboBoxEvents() { connect(configBox, static_cast(&QComboBox::currentIndexChanged), this, &JoyTabWidget::changeJoyConfig, Qt::QueuedConnection); connect(configBox, static_cast(&QComboBox::currentIndexChanged), this, &JoyTabWidget::removeProfileEditNotification, Qt::QueuedConnection); connect(m_joystick, &InputDevice::profileNameEdited, this, &JoyTabWidget::editCurrentProfileItemText); } void JoyTabWidget::disconnectCheckUnsavedEvent() { disconnect(configBox, static_cast(&QComboBox::currentIndexChanged), this, &JoyTabWidget::checkForUnsavedProfile); } void JoyTabWidget::reconnectCheckUnsavedEvent() { connect(configBox, static_cast(&QComboBox::currentIndexChanged), this, &JoyTabWidget::checkForUnsavedProfile); } void JoyTabWidget::refreshButtons() { removeCurrentButtons(); fillButtons(); } void JoyTabWidget::checkStickDisplay() { JoyControlStickButton *button = qobject_cast(sender()); // static_cast JoyControlStick *stick = button->getStick(); if ((stick != nullptr) && stick->hasSlotsAssigned()) { SetJoystick *currentSet = m_joystick->getActiveSetJoystick(); removeSetButtons(currentSet); fillSetButtons(currentSet); } } void JoyTabWidget::checkSensorDisplay() { JoySensorButton *button = qobject_cast(sender()); JoySensor *sensor = button->getSensor(); if ((sensor != nullptr) && sensor->hasSlotsAssigned()) { SetJoystick *currentSet = m_joystick->getActiveSetJoystick(); removeSetButtons(currentSet); fillSetButtons(currentSet); } } void JoyTabWidget::checkDPadButtonDisplay() { JoyDPadButton *button = qobject_cast(sender()); // static_cast JoyDPad *dpad = button->getDPad(); if ((dpad != nullptr) && dpad->hasSlotsAssigned()) { SetJoystick *currentSet = m_joystick->getActiveSetJoystick(); removeSetButtons(currentSet); fillSetButtons(currentSet); } } void JoyTabWidget::checkAxisButtonDisplay() { JoyAxisButton *button = qobject_cast(sender()); // static_cast if (button->getAssignedSlots()->count() > 0) { SetJoystick *currentSet = m_joystick->getActiveSetJoystick(); removeSetButtons(currentSet); fillSetButtons(currentSet); } } // IT CAN BE HERE void JoyTabWidget::checkButtonDisplay() { JoyButton *button = qobject_cast(sender()); // static_cast if (button->getAssignedSlots()->count() > 0) { SetJoystick *currentSet = m_joystick->getActiveSetJoystick(); removeSetButtons(currentSet); fillSetButtons(currentSet); } } void JoyTabWidget::checkStickEmptyDisplay() { StickPushButtonGroup *group = qobject_cast(sender()); // static_cast JoyControlStick *stick = group->getStick(); // JoyControlStickButton *button = static_cast(sender()); // JoyControlStick *stick = button->getStick(); if ((stick != nullptr) && !stick->hasSlotsAssigned()) { SetJoystick *currentSet = m_joystick->getActiveSetJoystick(); removeSetButtons(currentSet); fillSetButtons(currentSet); } } void JoyTabWidget::checkSensorEmptyDisplay() { SensorPushButtonGroup *group = qobject_cast(sender()); JoySensor *sensor = group->getSensor(); if ((sensor != nullptr) && !sensor->hasSlotsAssigned()) { SetJoystick *currentSet = m_joystick->getActiveSetJoystick(); removeSetButtons(currentSet); fillSetButtons(currentSet); } } void JoyTabWidget::checkDPadButtonEmptyDisplay() { DPadPushButtonGroup *group = qobject_cast(sender()); // static_cast JoyDPad *dpad = group->getDPad(); // JoyDPadButton *button = static_cast(sender()); // JoyDPad *dpad = button->getDPad(); if ((dpad != nullptr) && !dpad->hasSlotsAssigned()) { SetJoystick *currentSet = m_joystick->getActiveSetJoystick(); removeSetButtons(currentSet); fillSetButtons(currentSet); } } void JoyTabWidget::checkAxisButtonEmptyDisplay() { JoyAxisButton *button = qobject_cast(sender()); // static_cast if (button->getAssignedSlots()->count() == 0) { SetJoystick *currentSet = m_joystick->getActiveSetJoystick(); removeSetButtons(currentSet); fillSetButtons(currentSet); } } void JoyTabWidget::checkButtonEmptyDisplay() { JoyButton *button = qobject_cast(sender()); // static_cast if (button->getAssignedSlots()->count() == 0) { SetJoystick *currentSet = m_joystick->getActiveSetJoystick(); removeSetButtons(currentSet); fillSetButtons(currentSet); } } void JoyTabWidget::checkHideEmptyOption() { bool currentHideEmptyButtons = m_settings->value("HideEmptyButtons", false).toBool(); if (currentHideEmptyButtons != hideEmptyButtons) { hideEmptyButtons = currentHideEmptyButtons; refreshButtons(); } } void JoyTabWidget::fillSetButtons(SetJoystick *set) { int row = 0; int column = 0; // QWidget *child = 0; QGridLayout *current_layout = nullptr; switch (set->getIndex()) { case 0: { current_layout = gridLayout; break; } case 1: { current_layout = gridLayout2; break; } case 2: { current_layout = gridLayout3; break; } case 3: { current_layout = gridLayout4; break; } case 4: { current_layout = gridLayout5; break; } case 5: { current_layout = gridLayout6; break; } case 6: { current_layout = gridLayout7; break; } case 7: { current_layout = gridLayout8; break; } default: break; } SetJoystick *currentSet = set; currentSet->establishPropertyUpdatedConnection(); QGridLayout *stickGrid = nullptr; QGroupBox *stickGroup = nullptr; int stickGridColumn = 0; int stickGridRow = 0; for (int j = 0; j < m_joystick->getNumberSticks(); j++) { JoyControlStick *stick = currentSet->getJoyStick(j); stick->establishPropertyUpdatedConnection(); QHash *stickButtons = stick->getButtons(); if (!hideEmptyButtons || stick->hasSlotsAssigned()) { if (stickGroup == nullptr) { stickGroup = new QGroupBox(tr("Sticks"), this); } if (stickGrid == nullptr) { stickGrid = new QGridLayout(); stickGridColumn = 0; stickGridRow = 0; } QWidget *groupContainer = new QWidget(stickGroup); StickPushButtonGroup *stickButtonGroup = new StickPushButtonGroup(stick, isKeypadUnlocked(), displayingNames, groupContainer); if (hideEmptyButtons) { connect(stickButtonGroup, &StickPushButtonGroup::buttonSlotChanged, this, &JoyTabWidget::checkStickEmptyDisplay); } connect(namesPushButton, &QPushButton::clicked, stickButtonGroup, &StickPushButtonGroup::toggleNameDisplay); if (stickGridColumn > 1) { stickGridColumn = 0; stickGridRow++; } groupContainer->setLayout(stickButtonGroup); stickGrid->addWidget(groupContainer, stickGridRow, stickGridColumn); stickGridColumn++; } else { QHashIterator tempiter(*stickButtons); while (tempiter.hasNext()) { JoyControlStickButton *button = tempiter.next().value(); button->establishPropertyUpdatedConnections(); connect(button, &JoyControlStickButton::slotsChanged, this, &JoyTabWidget::checkStickDisplay); } } } if (stickGroup != nullptr) { QSpacerItem *tempspacer = new QSpacerItem(10, 4, QSizePolicy::Minimum, QSizePolicy::Fixed); QVBoxLayout *tempvbox = new QVBoxLayout; tempvbox->addLayout(stickGrid); tempvbox->addItem(tempspacer); stickGroup->setLayout(tempvbox); current_layout->addWidget(stickGroup, row, column, 1, 2, Qt::AlignTop); row++; } column = 0; QGridLayout *sensorGrid = nullptr; QGroupBox *sensorGroup = nullptr; int sensorGridColumn = 0; int sensorGridRow = 0; for (size_t i = 0; i < SENSOR_COUNT; ++i) { JoySensorType type = static_cast(i); if (!m_joystick->hasSensor(type)) continue; JoySensor *sensor = currentSet->getSensor(type); sensor->establishPropertyUpdatedConnection(); QHash *sensorButtons = sensor->getButtons(); if (!hideEmptyButtons || sensor->hasSlotsAssigned()) { if (sensorGroup == nullptr) sensorGroup = new QGroupBox(tr("Sensors"), this); if (sensorGrid == nullptr) { sensorGrid = new QGridLayout(); sensorGridColumn = 0; sensorGridRow = 0; } QWidget *groupContainer = new QWidget(sensorGroup); SensorPushButtonGroup *sensorButtonGroup = new SensorPushButtonGroup(sensor, isKeypadUnlocked(), displayingNames, groupContainer); if (hideEmptyButtons) { connect(sensorButtonGroup, &SensorPushButtonGroup::buttonSlotChanged, this, &JoyTabWidget::checkSensorEmptyDisplay); } connect(namesPushButton, &QPushButton::clicked, sensorButtonGroup, &SensorPushButtonGroup::toggleNameDisplay); if (sensorGridColumn > 1) { sensorGridColumn = 0; sensorGridRow++; } groupContainer->setLayout(sensorButtonGroup); sensorGrid->addWidget(groupContainer, sensorGridRow, sensorGridColumn); sensorGridColumn++; } else { for (auto iter = sensorButtons->cbegin(); iter != sensorButtons->cend(); ++iter) { JoySensorButton *button = iter.value(); button->establishPropertyUpdatedConnections(); connect(button, &JoySensorButton::slotsChanged, this, &JoyTabWidget::checkSensorDisplay); } } } if (sensorGroup != nullptr) { QSpacerItem *tempspacer = new QSpacerItem(10, 4, QSizePolicy::Minimum, QSizePolicy::Fixed); QVBoxLayout *tempvbox = new QVBoxLayout; tempvbox->addLayout(sensorGrid); tempvbox->addItem(tempspacer); sensorGroup->setLayout(tempvbox); current_layout->addWidget(sensorGroup, row, column, 1, 2, Qt::AlignTop); row++; } QGridLayout *hatGrid = nullptr; QGroupBox *hatGroup = nullptr; int hatGridColumn = 0; int hatGridRow = 0; for (int j = 0; j < m_joystick->getNumberHats(); j++) { JoyDPad *dpad = currentSet->getJoyDPad(j); dpad->establishPropertyUpdatedConnection(); QHash *buttons = dpad->getJoyButtons(); if (!hideEmptyButtons || dpad->hasSlotsAssigned()) { if (hatGroup == nullptr) { hatGroup = new QGroupBox(tr("DPads"), this); } if (hatGrid == nullptr) { hatGrid = new QGridLayout(); hatGridColumn = 0; hatGridRow = 0; } QWidget *groupContainer = new QWidget(hatGroup); DPadPushButtonGroup *dpadButtonGroup = new DPadPushButtonGroup(dpad, isKeypadUnlocked(), displayingNames, groupContainer); if (hideEmptyButtons) { connect(dpadButtonGroup, &DPadPushButtonGroup::buttonSlotChanged, this, &JoyTabWidget::checkDPadButtonEmptyDisplay); } connect(namesPushButton, &QPushButton::clicked, dpadButtonGroup, &DPadPushButtonGroup::toggleNameDisplay); if (hatGridColumn > 1) { hatGridColumn = 0; hatGridRow++; } groupContainer->setLayout(dpadButtonGroup); hatGrid->addWidget(groupContainer, hatGridRow, hatGridColumn); hatGridColumn++; } else { QHashIterator tempiter(*buttons); while (tempiter.hasNext()) { JoyDPadButton *button = tempiter.next().value(); button->establishPropertyUpdatedConnections(); connect(button, &JoyDPadButton::slotsChanged, this, &JoyTabWidget::checkDPadButtonDisplay); } } } for (int j = 0; j < m_joystick->getNumberVDPads(); j++) { VDPad *vdpad = currentSet->getVDPad(j); vdpad->establishPropertyUpdatedConnection(); QHash *buttons = vdpad->getButtons(); if (!hideEmptyButtons || vdpad->hasSlotsAssigned()) { if (hatGroup == nullptr) { hatGroup = new QGroupBox(tr("DPads"), this); } if (hatGrid == nullptr) { hatGrid = new QGridLayout(); hatGridColumn = 0; hatGridRow = 0; } QWidget *groupContainer = new QWidget(hatGroup); DPadPushButtonGroup *dpadButtonGroup = new DPadPushButtonGroup(vdpad, isKeypadUnlocked(), displayingNames, groupContainer); if (hideEmptyButtons) { connect(dpadButtonGroup, &DPadPushButtonGroup::buttonSlotChanged, this, &JoyTabWidget::checkDPadButtonEmptyDisplay); } connect(namesPushButton, &QPushButton::clicked, dpadButtonGroup, &DPadPushButtonGroup::toggleNameDisplay); if (hatGridColumn > 1) { hatGridColumn = 0; hatGridRow++; } groupContainer->setLayout(dpadButtonGroup); hatGrid->addWidget(groupContainer, hatGridRow, hatGridColumn); hatGridColumn++; } else { QHashIterator tempiter(*buttons); while (tempiter.hasNext()) { JoyDPadButton *button = tempiter.next().value(); button->establishPropertyUpdatedConnections(); connect(button, &JoyDPadButton::slotsChanged, this, &JoyTabWidget::checkDPadButtonDisplay); } } } if (hatGroup != nullptr) { QSpacerItem *tempspacer = new QSpacerItem(10, 4, QSizePolicy::Minimum, QSizePolicy::Fixed); QVBoxLayout *tempvbox = new QVBoxLayout; tempvbox->addLayout(hatGrid); tempvbox->addItem(tempspacer); hatGroup->setLayout(tempvbox); current_layout->addWidget(hatGroup, row, column, 1, 2, Qt::AlignTop); row++; } column = 0; for (int j = 0; j < m_joystick->getNumberAxes(); j++) { JoyAxis *axis = currentSet->getJoyAxis(j); if (!axis->isPartControlStick() && axis->hasControlOfButtons()) { JoyAxisButton *paxisbutton = axis->getPAxisButton(); JoyAxisButton *naxisbutton = axis->getNAxisButton(); if (!hideEmptyButtons || ((paxisbutton->getAssignedSlots()->count() > 0) || (naxisbutton->getAssignedSlots()->count() > 0))) { JoyAxisWidget *axisWidget = new JoyAxisWidget(axis, displayingNames, this); axisWidget->setText(axis->getName()); axisWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); axisWidget->setMinimumSize(200, 24); connect(axisWidget, &JoyAxisWidget::clicked, this, &JoyTabWidget::showAxisDialog); connect(namesPushButton, &QPushButton::clicked, axisWidget, &JoyAxisWidget::toggleNameDisplay); if (hideEmptyButtons) { connect(paxisbutton, &JoyAxisButton::slotsChanged, this, &JoyTabWidget::checkAxisButtonEmptyDisplay); connect(naxisbutton, &JoyAxisButton::slotsChanged, this, &JoyTabWidget::checkAxisButtonEmptyDisplay); } if (column > 1) { column = 0; row++; } current_layout->addWidget(axisWidget, row, column); column++; } else { paxisbutton->establishPropertyUpdatedConnections(); naxisbutton->establishPropertyUpdatedConnections(); connect(paxisbutton, &JoyAxisButton::slotsChanged, this, &JoyTabWidget::checkAxisButtonDisplay); connect(naxisbutton, &JoyAxisButton::slotsChanged, this, &JoyTabWidget::checkAxisButtonDisplay); } } } for (int j = 0; j < m_joystick->getNumberButtons(); j++) { JoyButton *button = currentSet->getJoyButton(j); if ((button != nullptr) && !button->isPartVDPad()) { button->establishPropertyUpdatedConnections(); if (!hideEmptyButtons || (button->getAssignedSlots()->count() > 0)) { qDebug() << "Button in joytabwidget " << button->getName() << " has " << button->getAssignedSlots()->count() << " assignments"; for (auto it : *button->getAssignedSlots()) { qDebug() << "slotMode: " << it->getSlotMode(); if (it->getSlotMode() == 15) { for (auto it2 : *it->getMixSlots()) { qDebug() << "mixslot: " << it2->getSlotString(); } } } JoyButtonWidget *buttonWidget = new JoyButtonWidget(button, displayingNames, this); buttonWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); buttonWidget->setText(buttonWidget->text()); buttonWidget->setMinimumSize(200, 24); connect(buttonWidget, &JoyButtonWidget::clicked, this, &JoyTabWidget::showButtonDialog); connect(namesPushButton, &QPushButton::clicked, buttonWidget, &JoyButtonWidget::toggleNameDisplay); if (hideEmptyButtons) { connect(button, &JoyButton::slotsChanged, this, &JoyTabWidget::checkButtonEmptyDisplay); } if (column > 1) { column = 0; row++; } current_layout->addWidget(buttonWidget, row, column); column++; } else { button->establishPropertyUpdatedConnections(); connect(button, &JoyButton::slotsChanged, this, &JoyTabWidget::checkButtonDisplay); } } } if (current_layout->count() == 0) { QLabel *newlabel = new QLabel(tr("No buttons have been assigned. Please use Quick Set to assign keys\nto buttons or " "disable hiding empty buttons.")); current_layout->addWidget(newlabel, 0, 0, Qt::AlignCenter); } } void JoyTabWidget::removeSetButtons(SetJoystick *set) { SetJoystick *currentSet = set; currentSet->disconnectPropertyUpdatedConnection(); QLayoutItem *child = nullptr; QGridLayout *current_layout = nullptr; switch (currentSet->getIndex()) { case 0: { current_layout = gridLayout; break; } case 1: { current_layout = gridLayout2; break; } case 2: { current_layout = gridLayout3; break; } case 3: { current_layout = gridLayout4; break; } case 4: { current_layout = gridLayout5; break; } case 5: { current_layout = gridLayout6; break; } case 6: { current_layout = gridLayout7; break; } case 7: { current_layout = gridLayout8; break; } default: { break; } } while (current_layout && ((child = current_layout->takeAt(0)) != nullptr)) { current_layout->removeWidget(child->widget()); child->widget()->deleteLater(); delete child; child = nullptr; } for (int j = 0; j < m_joystick->getNumberSticks(); j++) { JoyControlStick *stick = currentSet->getJoyStick(j); stick->disconnectPropertyUpdatedConnection(); QHash *stickButtons = stick->getButtons(); QHashIterator tempiter(*stickButtons); while (tempiter.hasNext()) { JoyControlStickButton *button = tempiter.next().value(); button->disconnectPropertyUpdatedConnections(); disconnect(button, &JoyControlStickButton::slotsChanged, this, &JoyTabWidget::checkStickDisplay); disconnect(button, &JoyControlStickButton::slotsChanged, this, &JoyTabWidget::checkStickEmptyDisplay); } } for (int j = 0; j < m_joystick->getNumberHats(); j++) { JoyDPad *dpad = currentSet->getJoyDPad(j); dpad->establishPropertyUpdatedConnection(); QHash *buttons = dpad->getJoyButtons(); QHashIterator tempiter(*buttons); while (tempiter.hasNext()) { JoyDPadButton *button = tempiter.next().value(); button->disconnectPropertyUpdatedConnections(); disconnect(button, &JoyDPadButton::slotsChanged, this, &JoyTabWidget::checkDPadButtonDisplay); disconnect(button, &JoyDPadButton::slotsChanged, this, &JoyTabWidget::checkDPadButtonEmptyDisplay); } } for (int j = 0; j < m_joystick->getNumberVDPads(); j++) { VDPad *vdpad = currentSet->getVDPad(j); vdpad->establishPropertyUpdatedConnection(); QHash *buttons = vdpad->getButtons(); QHashIterator tempiter(*buttons); while (tempiter.hasNext()) { JoyDPadButton *button = tempiter.next().value(); button->disconnectPropertyUpdatedConnections(); disconnect(button, &JoyDPadButton::slotsChanged, this, &JoyTabWidget::checkDPadButtonDisplay); disconnect(button, &JoyDPadButton::slotsChanged, this, &JoyTabWidget::checkDPadButtonEmptyDisplay); } } for (int j = 0; j < m_joystick->getNumberAxes(); j++) { JoyAxis *axis = currentSet->getJoyAxis(j); if (!axis->isPartControlStick() && axis->hasControlOfButtons()) { JoyAxisButton *paxisbutton = axis->getPAxisButton(); JoyAxisButton *naxisbutton = axis->getNAxisButton(); paxisbutton->disconnectPropertyUpdatedConnections(); naxisbutton->disconnectPropertyUpdatedConnections(); disconnect(paxisbutton, &JoyAxisButton::slotsChanged, this, &JoyTabWidget::checkAxisButtonDisplay); disconnect(naxisbutton, &JoyAxisButton::slotsChanged, this, &JoyTabWidget::checkAxisButtonDisplay); disconnect(paxisbutton, &JoyAxisButton::slotsChanged, this, &JoyTabWidget::checkAxisButtonEmptyDisplay); disconnect(naxisbutton, &JoyAxisButton::slotsChanged, this, &JoyTabWidget::checkAxisButtonEmptyDisplay); } } for (int j = 0; j < m_joystick->getNumberButtons(); j++) { JoyButton *button = currentSet->getJoyButton(j); if ((button != nullptr) && !button->isPartVDPad()) { button->disconnectPropertyUpdatedConnections(); disconnect(button, &JoyButton::slotsChanged, this, &JoyTabWidget::checkButtonDisplay); disconnect(button, &JoyButton::slotsChanged, this, &JoyTabWidget::checkButtonEmptyDisplay); } } } void JoyTabWidget::editCurrentProfileItemText(QString text) { int currentIndex = configBox->currentIndex(); if (currentIndex >= 0) { if (!text.isEmpty()) { configBox->setItemText(currentIndex, text); } else if (currentIndex == 0) { configBox->setItemText(currentIndex, tr("")); } else if (currentIndex > 0) { QFileInfo profileName(configBox->itemData(currentIndex).toString()); configBox->setItemText(currentIndex, PadderCommon::getProfileName(profileName)); } } } void JoyTabWidget::refreshCopySetActions() { copySetMenu->clear(); for (int i = 0; i < GlobalVariables::InputDevice::NUMBER_JOYSETS; i++) { SetJoystick *tempSet = m_joystick->getSetJoystick(i); QAction *newaction = nullptr; if (!tempSet->getName().isEmpty()) { QString tempName = tempSet->getName(); QString tempNameEscaped = tempName; tempNameEscaped.replace("&", "&&"); newaction = new QAction(tr("Set %1: %2").arg(i + 1).arg(tempNameEscaped), copySetMenu); } else { newaction = new QAction(tr("Set %1").arg(i + 1), copySetMenu); } newaction->setData(i); connect(newaction, &QAction::triggered, this, &JoyTabWidget::performSetCopy); copySetMenu->addAction(newaction); } connect(copySetMenu, &QMenu::aboutToShow, this, &JoyTabWidget::disableCopyCurrentSet); } void JoyTabWidget::performSetCopy() { QAction *action = qobject_cast(sender()); // static_cast int sourceSetIndex = action->data().toInt(); SetJoystick *sourceSet = m_joystick->getSetJoystick(sourceSetIndex); QString sourceName = QString(); if (!sourceSet->getName().isEmpty()) { QString tempNameEscaped = sourceSet->getName(); tempNameEscaped.replace("&", "&&"); sourceName = tr("Set %1: %2").arg(sourceSetIndex + 1).arg(tempNameEscaped); } else { sourceName = tr("Set %1").arg(sourceSetIndex + 1); } SetJoystick *destSet = m_joystick->getActiveSetJoystick(); if ((sourceSet != nullptr) && (destSet != nullptr)) { QMessageBox msgBox; msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setWindowTitle(tr("Copy Set Assignments")); msgBox.setText(tr("Are you sure you want to copy the assignments and device properties from %1?").arg(sourceName)); int status = msgBox.exec(); if (status == QMessageBox::Yes) { PadderCommon::lockInputDevices(); removeSetButtons(destSet); QMetaObject::invokeMethod(sourceSet, "copyAssignments", Qt::BlockingQueuedConnection, Q_ARG(SetJoystick *, destSet)); // sourceSet->copyAssignments(destSet); fillSetButtons(destSet); PadderCommon::unlockInputDevices(); } } } void JoyTabWidget::disableCopyCurrentSet() { SetJoystick *activeSet = m_joystick->getActiveSetJoystick(); QMenu *menu = qobject_cast(sender()); // static_cast QList actions = menu->actions(); QListIterator iter(actions); while (iter.hasNext()) { QAction *action = iter.next(); if (action->data().toInt() == activeSet->getIndex()) { action->setEnabled(false); } else { action->setEnabled(true); } } } void JoyTabWidget::openGameControllerMappingWindow() { GameControllerMappingDialog *dialog = new GameControllerMappingDialog(m_joystick, m_settings, this); dialog->show(); connect(dialog, &GameControllerMappingDialog::mappingUpdate, this, &JoyTabWidget::propogateMappingUpdate); } void JoyTabWidget::propogateMappingUpdate(QString mapping, InputDevice *device) { emit mappingUpdated(mapping, device); } void JoyTabWidget::refreshHelperThread() { tabHelper.moveToThread(m_joystick->thread()); } void JoyTabWidget::changeEvent(QEvent *event) { if (event->type() == QEvent::LanguageChange) { retranslateUi(); } QWidget::changeEvent(event); } void JoyTabWidget::convToUniqueIDControllerGroupSett(QSettings *sett, QString guidControllerSett, QString uniqueControllerSett) { if (sett->contains(guidControllerSett)) { sett->setValue(uniqueControllerSett, sett->value(guidControllerSett)); sett->remove(guidControllerSett); } } void JoyTabWidget::updateBatteryIcon() { SDL_JoystickPowerLevel power_level = SDL_JoystickCurrentPowerLevel(m_joystick->getJoyHandle()); if (m_old_power_level == power_level) { return; } switch (power_level) { case SDL_JOYSTICK_POWER_EMPTY: batteryIcon->setVisible(true); batteryIcon->setPixmap(PadderCommon::loadIcon("battery-empty").pixmap(QSize(20, 20))); break; case SDL_JOYSTICK_POWER_LOW: batteryIcon->setVisible(true); batteryIcon->setPixmap(PadderCommon::loadIcon("battery-low").pixmap(QSize(20, 20))); break; case SDL_JOYSTICK_POWER_MEDIUM: batteryIcon->setVisible(true); batteryIcon->setPixmap(PadderCommon::loadIcon("battery-good").pixmap(QSize(20, 20))); break; case SDL_JOYSTICK_POWER_FULL: case SDL_JOYSTICK_POWER_MAX: batteryIcon->setVisible(true); batteryIcon->setPixmap(PadderCommon::loadIcon("battery-full").pixmap(QSize(20, 20))); break; case SDL_JOYSTICK_POWER_UNKNOWN: batteryIcon->setVisible(false); break; case SDL_JOYSTICK_POWER_WIRED: batteryIcon->setVisible(true); batteryIcon->setPixmap(PadderCommon::loadIcon("battery-good-charging").pixmap(QSize(20, 20))); break; default: batteryIcon->setVisible(false); WARN() << "Unknown battery level:" << power_level << " for joystick: " << m_joystick->getName(); break; } m_old_power_level = power_level; } AntiMicroX-antimicrox-b300273/src/gui/joytabwidget.h000066400000000000000000000167751471077622000224120ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYTABWIDGET_H #define JOYTABWIDGET_H #include #include #include #include "uihelpers/joytabwidgethelper.h" class InputDevice; class AntiMicroSettings; class QEvent; class SetJoystick; class QVBoxLayout; class QHBoxLayout; class QGridLayout; class QPushButton; class QComboBox; class QSpacerItem; class AxisEditDialog; class QAction; class QMenu; class QStackedWidget; class QSettings; /** * @brief Widget containing tab representing selected joystick. * * It is visible in main window of application. */ class JoyTabWidget : public QWidget { Q_OBJECT public: explicit JoyTabWidget(InputDevice *joystick, AntiMicroSettings *settings, QWidget *parent = nullptr); void saveSettings(); // JoyTabSettings class void loadSettings(bool forceRefresh = false); // JoyTabSettings class void setCurrentConfig(int index); // JoyTabSettings class void unloadConfig(); // JoyTabSettings class void checkHideEmptyOption(); void refreshHelperThread(); void convToUniqueIDControllerGroupSett(QSettings *sett, QString guidControllerSett, QString uniqueControllerSett); bool isDisplayingNames(); bool discardUnsavedProfileChanges(); bool static changesNotSaved(); int getCurrentConfigIndex(); // JoyTabSettings class QHash *recentConfigs(); // JoyTabSettings class QString getCurrentConfigName(); // JoyTabSettings class QString getConfigName(int index); InputDevice *getJoystick(); protected: virtual void changeEvent(QEvent *event); void removeCurrentButtons(); void retranslateUi(); void disconnectMainComboBoxEvents(); void reconnectMainComboBoxEvents(); void disconnectCheckUnsavedEvent(); void reconnectCheckUnsavedEvent(); void fillSetButtons(SetJoystick *set); // JoyTabWidgetSets class void removeSetButtons(SetJoystick *set); // JoyTabWidgetSets class bool isKeypadUnlocked(); static const int DEFAULTNUMBERPROFILES = 5; signals: void joystickConfigChanged(int index); // JoyTabSettings class void joystickAxisRefreshLabels(int axisIndex); void namesDisplayChanged(bool status); void forceTabUnflash(JoyTabWidget *tabWidget); void mappingUpdated(QString mapping, InputDevice *device); public slots: void openConfigFileDialog(); // JoyTabSettings class void fillButtons(); // JoyTabWidgetSets class void saveDeviceSettings(bool sync = false); // JoyTabSettings class void loadDeviceSettings(); // JoyTabSettings class void changeNameDisplay(bool displayNames); void changeCurrentSet(int index); // JoyTabWidgetSets class void loadConfigFile(QString fileLocation); // JoyTabSettings class void refreshButtons(); private slots: void saveConfigFile(); // JoyTabSettings class void resetJoystick(); void saveAsConfig(); // JoyTabSettings class void removeConfig(); // JoyTabSettings class void changeJoyConfig(int index); // JoyTabSettings class void showAxisDialog(); void showButtonDialog(); void showStickAssignmentDialog(); void showQuickSetDialog(); void showKeyDelayDialog(); void showSetNamesDialog(); // JoyTabWidgetSets class void toggleNames(); void updateBatteryIcon(); void changeSetOne(); // JoyTabWidgetSets class void changeSetTwo(); // JoyTabWidgetSets class void changeSetThree(); // JoyTabWidgetSets class void changeSetFour(); // JoyTabWidgetSets class void changeSetFive(); // JoyTabWidgetSets class void changeSetSix(); // JoyTabWidgetSets class void changeSetSeven(); // JoyTabWidgetSets class void changeSetEight(); // JoyTabWidgetSets class void displayProfileEditNotification(); void removeProfileEditNotification(); void checkForUnsavedProfile(int newindex = -1); void checkStickDisplay(); void checkSensorDisplay(); void checkDPadButtonDisplay(); void checkAxisButtonDisplay(); void checkButtonDisplay(); void checkStickEmptyDisplay(); void checkSensorEmptyDisplay(); void checkDPadButtonEmptyDisplay(); void checkAxisButtonEmptyDisplay(); void checkButtonEmptyDisplay(); void editCurrentProfileItemText(QString text); void refreshCopySetActions(); // JoyTabWidgetSets class void performSetCopy(); // JoyTabWidgetSets class void disableCopyCurrentSet(); // JoyTabWidgetSets class void refreshSetButtons(); // JoyTabWidgetSets class void openGameControllerMappingWindow(); void propogateMappingUpdate(QString mapping, InputDevice *device); private: QVBoxLayout *verticalLayout; QHBoxLayout *configHorizontalLayout; QLabel *batteryIcon; QPushButton *removeButton; QPushButton *loadButton; QPushButton *saveButton; QPushButton *resetButton; QPushButton *namesPushButton; QPushButton *saveAsButton; QPushButton *delayButton; QComboBox *configBox; QGridLayout *gridLayout; QGridLayout *gridLayout2; QGridLayout *gridLayout3; QGridLayout *gridLayout4; QGridLayout *gridLayout5; QGridLayout *gridLayout6; QGridLayout *gridLayout7; QGridLayout *gridLayout8; QSpacerItem *spacer1; QSpacerItem *spacer2; QSpacerItem *spacer3; AxisEditDialog *axisDialog; QPushButton *setPushButton1; QPushButton *setPushButton2; QPushButton *setPushButton3; QPushButton *setPushButton4; QPushButton *setPushButton5; QPushButton *setPushButton6; QPushButton *setPushButton7; QPushButton *setPushButton8; QPushButton *setsMenuButton; QAction *setAction1; QAction *setAction2; QAction *setAction3; QAction *setAction4; QAction *setAction5; QAction *setAction6; QAction *setAction7; QAction *setAction8; QMenu *copySetMenu; QHBoxLayout *horizontalLayout_2; QHBoxLayout *horizontalLayout_3; QPushButton *stickAssignPushButton; QPushButton *quickSetPushButton; QPushButton *gameControllerMappingPushButton; QSpacerItem *verticalSpacer_2; QStackedWidget *stackedWidget_2; QWidget *page; QWidget *page_2; QWidget *page_3; QWidget *page_4; QWidget *page_5; QWidget *page_6; QWidget *page_7; QWidget *page_8; QPushButton *pushButton; QSpacerItem *verticalSpacer_3; InputDevice *m_joystick; bool displayingNames; static bool changedNotSaved; AntiMicroSettings *m_settings; int comboBoxIndex = 0; bool hideEmptyButtons = false; QString oldProfileName; JoyTabWidgetHelper tabHelper; SDL_JoystickPowerLevel m_old_power_level = SDL_JOYSTICK_POWER_UNKNOWN; QTimer *m_battery_updater; }; #endif // JOYTABWIDGET_H AntiMicroX-antimicrox-b300273/src/gui/joytabwidgetcontainer.cpp000066400000000000000000000070641471077622000246370ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joytabwidgetcontainer.h" #include "joystick.h" #include "joytabwidget.h" #include #include #include JoyTabWidgetContainer::JoyTabWidgetContainer(QWidget *parent) : QTabWidget(parent) { } int JoyTabWidgetContainer::addTab(QWidget *widget, const QString &string) { return QTabWidget::addTab(widget, string); } int JoyTabWidgetContainer::addTab(JoyTabWidget *widget, const QString &string) { InputDevice *joystick = widget->getJoystick(); if (joystick != nullptr) { enableFlashes(joystick); connect(widget, &JoyTabWidget::forceTabUnflash, this, &JoyTabWidgetContainer::unflashTab); } return QTabWidget::addTab(widget, string); } void JoyTabWidgetContainer::flash(InputDevice *joystick) { bool found = false; for (int i = 0; (i < tabBar()->count()) && !found; i++) { JoyTabWidget *tab = qobject_cast(widget(i)); // static_cast if ((tab != nullptr) && (tab->getJoystick() == joystick)) { tabBar()->setTabTextColor(i, Qt::red); found = true; } } } void JoyTabWidgetContainer::unflash(InputDevice *joystick) { bool found = false; for (int i = 0; (i < tabBar()->count()) && !found; i++) { JoyTabWidget *tab = qobject_cast(widget(i)); // static_cast if ((tab != nullptr) && (tab->getJoystick() == joystick)) { tabBar()->setTabTextColor(i, QApplication::palette().color(QPalette::Text)); found = true; } } } void JoyTabWidgetContainer::unflashTab(JoyTabWidget *tabWidget) { bool found = false; for (int i = 0; (i < tabBar()->count()) && !found; i++) { JoyTabWidget *tab = qobject_cast(widget(i)); // static_cast if (tab == tabWidget) { tabBar()->setTabTextColor(i, QApplication::palette().color(QPalette::Text)); } } } void JoyTabWidgetContainer::unflashAll() { for (int i = 0; i < tabBar()->count(); i++) { JoyTabWidget *tab = qobject_cast(widget(i)); // static_cast if (tab != nullptr) { tabBar()->setTabTextColor(i, QApplication::palette().color(QPalette::Text)); } } } void JoyTabWidgetContainer::disableFlashes(InputDevice *joystick) { unflashAll(); disconnect(joystick, &InputDevice::clicked, this, nullptr); disconnect(joystick, &InputDevice::released, this, nullptr); } void JoyTabWidgetContainer::enableFlashes(InputDevice *joystick) { connect( joystick, &InputDevice::clicked, this, [this, joystick] { flash(joystick); }, Qt::QueuedConnection); connect( joystick, &InputDevice::released, this, [this, joystick] { unflash(joystick); }, Qt::QueuedConnection); } AntiMicroX-antimicrox-b300273/src/gui/joytabwidgetcontainer.h000066400000000000000000000027771471077622000243120ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYTABWIDGETCONTAINER_H #define JOYTABWIDGETCONTAINER_H #include class QWidget; class JoyTabWidget; class InputDevice; class JoyTabWidgetContainer : public QTabWidget { Q_OBJECT public: explicit JoyTabWidgetContainer(QWidget *parent = nullptr); int addTab(QWidget *widget, const QString &string); int addTab(JoyTabWidget *widget, const QString &string); public slots: void disableFlashes(InputDevice *joystick); void enableFlashes(InputDevice *joystick); private slots: void flash(InputDevice *joystick); void unflash(InputDevice *joystick); void unflashAll(); void unflashTab(JoyTabWidget *tabWidget); }; #endif // JOYTABWIDGETCONTAINER_H AntiMicroX-antimicrox-b300273/src/gui/mainsettingsdialog.cpp000066400000000000000000002162761471077622000241340ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2021 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mainsettingsdialog.h" #include "addeditautoprofiledialog.h" #include "antimicrosettings.h" #include "autoprofileinfo.h" #include "common.h" #include "editalldefaultautoprofiledialog.h" #include "eventhandlerfactory.h" #include "globalvariables.h" #include "inputdevice.h" #ifdef WITH_X11 #include "x11extras.h" #elif defined Q_OS_WIN #include "eventhandlerfactory.h" #include "winextras.h" #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static const QString RUNATSTARTUPREGKEY("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"); static const QString RUNATSTARTUPLOCATION(QString("%0\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\antimicrox.lnk") .arg(QString::fromUtf8(qgetenv("AppData")))); MainSettingsDialog::MainSettingsDialog(AntiMicroSettings *settings, QList *devices, QWidget *parent) : QDialog(parent, Qt::Dialog) , ui(new Ui::MainSettingsDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); ui->profileOpenDirPushButton->setIcon( PadderCommon::loadIcon("document-open", ":/images/actions/document_open_folder.png")); ui->logFilePushButton->setIcon(PadderCommon::loadIcon("document-open", ":/images/actions/document_open_folder.png")); this->settings = settings; this->allDefaultProfile = nullptr; this->connectedDevices = devices; fillControllerMappingsTable(); settings->getLock()->lock(); bool attachedNumKeypad = settings->value("AttachNumKeypad", false).toBool(); QString defaultProfileDir = settings->value("DefaultProfileDir", "").toString(); int numberRecentProfiles = settings->value("NumberRecentProfiles", 5).toInt(); bool closeToTray = settings->value("CloseToTray", false).toBool(); if (!defaultProfileDir.isEmpty() && QDir(defaultProfileDir).exists()) { ui->profileDefaultDirLineEdit->setText(defaultProfileDir); } else { ui->profileDefaultDirLineEdit->setText(PadderCommon::preferredProfileDir(settings)); } ui->numberRecentProfileSpinBox->setValue(numberRecentProfiles); if (closeToTray) { ui->closeToTrayCheckBox->setChecked(true); } changePresetLanguage(); #ifdef Q_OS_WIN ui->autoProfileTableWidget->hideColumn(3); #endif ui->autoProfileTableWidget->hideColumn(7); #if defined(WITH_X11) if (QApplication::platformName() == QStringLiteral("xcb")) { populateAutoProfiles(); fillAllAutoProfilesTable(); fillGUIDComboBox(); } else { delete ui->categoriesListWidget->item(3); ui->stackedWidget->removeWidget(ui->autoProfileSettingsPage); ui->categoriesListWidget->addItem(tr("AutoProfile (disabled in Wayland)")); auto item = ui->categoriesListWidget->item(ui->categoriesListWidget->count() - 1); item->setFlags(item->flags() & ~Qt::ItemIsEnabled); } #elif !defined(WITH_X11) && defined(Q_OS_UNIX) delete ui->categoriesListWidget->item(3); ui->stackedWidget->removeWidget(ui->autoProfileSettingsPage); #elif defined(Q_OS_WIN) populateAutoProfiles(); fillAllAutoProfilesTable(); fillGUIDComboBox(); #endif QString autoProfileActive = settings->value("AutoProfiles/AutoProfilesActive", "").toString(); if (autoProfileActive == "1") { ui->activeCheckBox->setChecked(true); ui->autoProfileTableWidget->setEnabled(true); ui->autoProfileAddPushButton->setEnabled(true); } #ifdef Q_OS_WIN BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); QFile tempFile(RUNATSTARTUPLOCATION); if (tempFile.exists()) { ui->launchAtWinStartupCheckBox->setChecked(true); } #else ui->launchAtWinStartupCheckBox->setVisible(false); // TODO #115 ui->keyRepeatGroupBox->setVisible(false); #endif bool useSingleProfileList = settings->value("TrayProfileList", false).toBool(); if (useSingleProfileList) { ui->traySingleProfileListCheckBox->setChecked(true); } #ifdef Q_OS_LINUX bool minimizeToTaskBar = settings->value("MinimizeToTaskbar", true).toBool(); #else bool minimizeToTaskBar = settings->value("MinimizeToTaskbar", false).toBool(); #endif if (minimizeToTaskBar) { ui->minimizeTaskbarCheckBox->setChecked(true); } bool hideEmpty = settings->value("HideEmptyButtons", false).toBool(); if (hideEmpty) { ui->hideEmptyCheckBox->setChecked(true); } bool autoOpenLastProfile = settings->value("AutoOpenLastProfile", true).toBool(); if (autoOpenLastProfile) { ui->autoLoadPreviousCheckBox->setChecked(true); } else { ui->autoLoadPreviousCheckBox->setChecked(false); } bool launchInTray = settings->value("LaunchInTray", false).toBool(); if (launchInTray) { ui->launchInTrayCheckBox->setChecked(true); } ui->showLowBatteryNotification->setChecked(settings->value("Notifications/notify_about_low_battery", true).toBool()); ui->showEmptyBatteryNotification->setChecked(settings->value("Notifications/notify_about_empty_battery", true).toBool()); #ifdef Q_OS_WIN bool associateProfiles = settings->value("AssociateProfiles", true).toBool(); if (associateProfiles) { ui->associateProfilesCheckBox->setChecked(true); } else { ui->associateProfilesCheckBox->setChecked(false); } bool disableEnhancedMouse = settings->value("Mouse/DisableWinEnhancedPointer", false).toBool(); if (disableEnhancedMouse) { ui->disableWindowsEnhancedPointCheckBox->setChecked(true); } #else ui->associateProfilesCheckBox->setVisible(false); ui->disableWindowsEnhancedPointCheckBox->setVisible(false); #endif if (attachedNumKeypad) ui->attachNumKeypadCheckbox->setChecked(true); bool smoothingEnabled = settings->value("Mouse/Smoothing", false).toBool(); if (smoothingEnabled) { ui->smoothingEnableCheckBox->setChecked(true); ui->historySizeSpinBox->setEnabled(true); ui->weightModifierDoubleSpinBox->setEnabled(true); } int historySize = settings->value("Mouse/HistorySize", 0).toInt(); if ((historySize > 0) && (historySize <= GlobalVariables::JoyButton::MAXIMUMMOUSEHISTORYSIZE)) { ui->historySizeSpinBox->setValue(historySize); } double weightModifier = settings->value("Mouse/WeightModifier", 0).toDouble(); if ((weightModifier > 0.0) && (weightModifier <= GlobalVariables::JoyButton::MAXIMUMWEIGHTMODIFIER)) { ui->weightModifierDoubleSpinBox->setValue(weightModifier); } for (int i = 1; i <= GlobalVariables::JoyButton::MAXIMUMMOUSEREFRESHRATE; i++) { ui->mouseRefreshRateComboBox->addItem(QString("%1 ms").arg(i), i); } int refreshIndex = ui->mouseRefreshRateComboBox->findData(GlobalVariables::JoyButton::mouseRefreshRate); if (refreshIndex >= 0) { ui->mouseRefreshRateComboBox->setCurrentIndex(refreshIndex); } #ifdef Q_OS_WIN QString tempTooltip = ui->mouseRefreshRateComboBox->toolTip(); tempTooltip.append("\n\n"); tempTooltip.append(tr("Also, Windows users who want to use a low value should also check the\n" "\"Disable Enhance Pointer Precision\" checkbox if you haven't disabled\n" "the option in Windows.")); ui->mouseRefreshRateComboBox->setToolTip(tempTooltip); #endif fillSpringScreenPresets(); for (int i = 1; i <= 16; i++) { ui->gamepadPollRateComboBox->addItem(QString("%1 ms").arg(i), QVariant(i)); } int gamepadPollIndex = ui->gamepadPollRateComboBox->findData(GlobalVariables::JoyButton::gamepadRefreshRate); if (gamepadPollIndex >= 0) { ui->gamepadPollRateComboBox->setCurrentIndex(gamepadPollIndex); } if (QApplication::platformName() == QStringLiteral("xcb")) { refreshExtraMouseInfo(); } else { ui->extraInfoFrame->hide(); } // Begin Advanced Tab QString curLogFile = settings->value("LogFile", "").toString(); int logLevel = settings->value("LogLevel", Logger::LOG_NONE).toInt(); if (!curLogFile.isEmpty()) { ui->logFilePathEdit->setText(curLogFile); } ui->logLevelComboBox->setCurrentIndex(logLevel); // End Advanced Tab settings->getLock()->unlock(); connect(ui->categoriesListWidget, &QListWidget::currentRowChanged, ui->stackedWidget, &QStackedWidget::setCurrentIndex); connect(ui->controllerMappingsTableWidget, &QTableWidget::itemChanged, this, &MainSettingsDialog::mappingsTableItemChanged); connect(ui->mappingDeletePushButton, &QPushButton::clicked, this, &MainSettingsDialog::deleteMappingRow); connect(ui->mappngInsertPushButton, &QPushButton::clicked, this, &MainSettingsDialog::insertMappingRow); connect(this, &MainSettingsDialog::accepted, this, &MainSettingsDialog::saveNewSettings); connect(ui->profileOpenDirPushButton, &QPushButton::clicked, this, &MainSettingsDialog::selectDefaultProfileDir); connect(ui->activeCheckBox, &QCheckBox::toggled, ui->autoProfileTableWidget, &QTableWidget::setEnabled); connect(ui->activeCheckBox, &QCheckBox::toggled, this, &MainSettingsDialog::autoProfileButtonsActiveState); connect(ui->devicesComboBox, static_cast(&QComboBox::activated), this, &MainSettingsDialog::changeDeviceForProfileTable); connect(ui->autoProfileTableWidget, &QTableWidget::itemChanged, this, &MainSettingsDialog::processAutoProfileActiveClick); connect(ui->autoProfileAddPushButton, &QPushButton::clicked, this, &MainSettingsDialog::openAddAutoProfileDialog); connect(ui->autoProfileDeletePushButton, &QPushButton::clicked, this, &MainSettingsDialog::openDeleteAutoProfileConfirmDialog); connect(ui->autoProfileEditPushButton, &QPushButton::clicked, this, &MainSettingsDialog::openEditAutoProfileDialog); connect(ui->autoProfileTableWidget, &QTableWidget::itemSelectionChanged, this, &MainSettingsDialog::changeAutoProfileButtonsState); connect(ui->keyRepeatEnableCheckBox, &QCheckBox::clicked, this, &MainSettingsDialog::changeKeyRepeatWidgetsStatus); connect(ui->keyDelayHorizontalSlider, &QSlider::valueChanged, ui->keyDelaySpinBox, &QSpinBox::setValue); connect(ui->keyDelaySpinBox, static_cast(&QSpinBox::valueChanged), ui->keyDelayHorizontalSlider, &QSlider::setValue); connect(ui->keyRateHorizontalSlider, &QSlider::valueChanged, ui->keyRateSpinBox, &QSpinBox::setValue); connect(ui->keyRateSpinBox, static_cast(&QSpinBox::valueChanged), ui->keyRateHorizontalSlider, &QSlider::setValue); connect(ui->smoothingEnableCheckBox, &QCheckBox::toggled, this, &MainSettingsDialog::checkSmoothingWidgetStatus); connect(ui->resetAccelPushButton, &QPushButton::clicked, this, &MainSettingsDialog::resetMouseAcceleration); // Advanced Tab connect(ui->logFilePushButton, &QPushButton::clicked, this, &MainSettingsDialog::selectLogFile); } MainSettingsDialog::~MainSettingsDialog() { if (connectedDevices != nullptr) { delete connectedDevices; connectedDevices = nullptr; } delete ui; } void MainSettingsDialog::fillControllerMappingsTable() { ui->controllerMappingsTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); QHash> tempHash; settings->getLock()->lock(); settings->beginGroup("Mappings"); QStringList mappings = settings->allKeys(); QStringListIterator iter(mappings); while (iter.hasNext()) { QString tempkey = iter.next(); QString tempGUID = QString(); if (tempkey.contains("Disable")) { bool disableGameController = settings->value(tempkey, false).toBool(); tempGUID = tempkey.remove("Disable"); insertTempControllerMapping(tempHash, tempGUID); if (tempHash.contains(tempGUID)) { QList templist = tempHash.value(tempGUID); templist.replace(2, QVariant(disableGameController)); tempHash.insert(tempGUID, templist); // Overwrite original list } } else { QString mappingString = settings->value(tempkey, QString()).toString(); if (!mappingString.isEmpty()) { tempGUID = tempkey; insertTempControllerMapping(tempHash, tempGUID); if (tempHash.contains(tempGUID)) { QList templist = tempHash.value(tempGUID); templist.replace(1, mappingString); tempHash.insert(tempGUID, templist); // Overwrite original list } } } } settings->endGroup(); settings->getLock()->unlock(); QHashIterator> iter2(tempHash); int i = 0; while (iter2.hasNext()) { ui->controllerMappingsTableWidget->insertRow(i); QList templist = iter2.next().value(); QTableWidgetItem *item = new QTableWidgetItem(templist.at(0).toString()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, iter2.key()); item->setToolTip(templist.at(0).toString()); ui->controllerMappingsTableWidget->setItem(i, 0, item); item = new QTableWidgetItem(templist.at(1).toString()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, iter2.key()); ui->controllerMappingsTableWidget->setItem(i, 1, item); bool disableController = templist.at(2).toBool(); item = new QTableWidgetItem(); item->setCheckState(disableController ? Qt::Checked : Qt::Unchecked); item->setData(Qt::UserRole, iter2.key()); ui->controllerMappingsTableWidget->setItem(i, 2, item); i++; } } void MainSettingsDialog::insertTempControllerMapping(QHash> &hash, QString newGUID) { if (!newGUID.isEmpty() && !hash.contains(newGUID)) { QList templist; templist.append(QVariant(newGUID)); templist.append(QVariant("")); templist.append(QVariant(false)); hash.insert(newGUID, templist); } } void MainSettingsDialog::mappingsTableItemChanged(QTableWidgetItem *item) { int column = item->column(); int row = item->row(); if ((column == 0) && !item->text().isEmpty()) { QTableWidgetItem *disableitem = ui->controllerMappingsTableWidget->item(row, column); if (disableitem != nullptr) { disableitem->setData(Qt::UserRole, item->text()); } item->setData(Qt::UserRole, item->text()); } } void MainSettingsDialog::insertMappingRow() { int insertRowIndex = ui->controllerMappingsTableWidget->rowCount(); ui->controllerMappingsTableWidget->insertRow(insertRowIndex); QTableWidgetItem *item = new QTableWidgetItem(); ui->controllerMappingsTableWidget->setItem(insertRowIndex, 0, item); item = new QTableWidgetItem(); item->setFlags(item->flags() & ~Qt::ItemIsEditable); ui->controllerMappingsTableWidget->setItem(insertRowIndex, 1, item); item = new QTableWidgetItem(); item->setCheckState(Qt::Unchecked); ui->controllerMappingsTableWidget->setItem(insertRowIndex, 2, item); } void MainSettingsDialog::deleteMappingRow() { int row = ui->controllerMappingsTableWidget->currentRow(); if (row >= 0) { ui->controllerMappingsTableWidget->removeRow(row); } } void MainSettingsDialog::syncMappingSettings() { settings->getLock()->lock(); settings->beginGroup("Mappings"); settings->remove(""); for (int i = 0; i < ui->controllerMappingsTableWidget->rowCount(); i++) { QTableWidgetItem *itemGUID = ui->controllerMappingsTableWidget->item(i, 0); QTableWidgetItem *itemMapping = ui->controllerMappingsTableWidget->item(i, 1); QTableWidgetItem *itemDisable = ui->controllerMappingsTableWidget->item(i, 2); if ((itemGUID != nullptr) && !itemGUID->text().isEmpty() && (itemDisable != nullptr)) { QString disableController = (itemDisable->checkState() == Qt::Checked) ? "1" : "0"; if ((itemMapping != nullptr) && !itemMapping->text().isEmpty()) { settings->setValue(itemGUID->text(), itemMapping->text()); } settings->setValue(QString("%1Disable").arg(itemGUID->text()), disableController); } } settings->endGroup(); settings->getLock()->unlock(); } void MainSettingsDialog::saveNewSettings() { syncMappingSettings(); settings->getLock()->lock(); QString oldProfileDir = settings->value("DefaultProfileDir", "").toString(); QString possibleProfileDir = ui->profileDefaultDirLineEdit->text(); bool closeToTray = ui->closeToTrayCheckBox->isChecked(); bool attachNumKeypad = ui->attachNumKeypadCheckbox->isChecked(); settings->setValue("AttachNumKeypad", attachNumKeypad ? "1" : "0"); if (oldProfileDir != possibleProfileDir) { if (QFileInfo(possibleProfileDir).exists()) { settings->setValue("DefaultProfileDir", possibleProfileDir); } else if (possibleProfileDir.isEmpty()) { settings->remove("DefaultProfileDir"); } } int numRecentProfiles = ui->numberRecentProfileSpinBox->value(); settings->setValue("NumberRecentProfiles", numRecentProfiles); if (closeToTray) { settings->setValue("CloseToTray", closeToTray ? "1" : "0"); } else { settings->remove("CloseToTray"); } settings->getLock()->unlock(); checkLocaleChange(); #if defined(WITH_X11) if (QApplication::platformName() == QStringLiteral("xcb")) { saveAutoProfileSettings(); } #else saveAutoProfileSettings(); #endif settings->getLock()->lock(); #ifdef Q_OS_WIN QFile tempFile(RUNATSTARTUPLOCATION); if (ui->launchAtWinStartupCheckBox->isChecked() && !tempFile.exists()) { if (tempFile.open(QFile::WriteOnly)) { QFile currentAppLocation(qApp->applicationFilePath()); currentAppLocation.link(QFileInfo(tempFile).absoluteFilePath()); } } else if (tempFile.exists() && QFileInfo(tempFile).isWritable()) { tempFile.remove(); } BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); #endif if (ui->traySingleProfileListCheckBox->isChecked()) { settings->setValue("TrayProfileList", "1"); } else { settings->setValue("TrayProfileList", "0"); } bool minimizeToTaskbar = ui->minimizeTaskbarCheckBox->isChecked(); settings->setValue("MinimizeToTaskbar", minimizeToTaskbar ? "1" : "0"); bool hideEmpty = ui->hideEmptyCheckBox->isChecked(); settings->setValue("HideEmptyButtons", hideEmpty ? "1" : "0"); bool autoOpenLastProfile = ui->autoLoadPreviousCheckBox->isChecked(); settings->setValue("AutoOpenLastProfile", autoOpenLastProfile ? "1" : "0"); bool launchInTray = ui->launchInTrayCheckBox->isChecked(); settings->setValue("LaunchInTray", launchInTray ? "1" : "0"); bool notify_bat_low = ui->showLowBatteryNotification->isChecked(); settings->setValue("Notifications/notify_about_low_battery", notify_bat_low); bool notify_bat_empty = ui->showEmptyBatteryNotification->isChecked(); settings->setValue("Notifications/notify_about_empty_battery", notify_bat_empty); #ifdef Q_OS_WIN bool associateProfiles = ui->associateProfilesCheckBox->isChecked(); settings->setValue("AssociateProfiles", associateProfiles ? "1" : "0"); bool associationExists = WinExtras::containsFileAssociationinRegistry(); if (associateProfiles && !associationExists) { WinExtras::writeFileAssocationToRegistry(); } else if (!associateProfiles && associationExists) { WinExtras::removeFileAssociationFromRegistry(); } bool disableEnhancePoint = ui->disableWindowsEnhancedPointCheckBox->isChecked(); bool oldEnhancedValue = settings->value("Mouse/DisableWinEnhancedPointer", false).toBool(); bool usingEnhancedPointer = WinExtras::isUsingEnhancedPointerPrecision(); settings->setValue("Mouse/DisableWinEnhancedPointer", disableEnhancePoint ? "1" : "0"); if (disableEnhancePoint != oldEnhancedValue) { if (usingEnhancedPointer && disableEnhancePoint) { WinExtras::disablePointerPrecision(); } else if (!usingEnhancedPointer && !disableEnhancePoint) { WinExtras::enablePointerPrecision(); } } #endif PadderCommon::lockInputDevices(); if (connectedDevices->size() > 0) { InputDevice *tempDevice = connectedDevices->at(0); QMetaObject::invokeMethod(tempDevice, "haltServices", Qt::BlockingQueuedConnection); } bool smoothingEnabled = ui->smoothingEnableCheckBox->isChecked(); int historySize = ui->historySizeSpinBox->value(); double weightModifier = ui->weightModifierDoubleSpinBox->value(); settings->setValue("Mouse/Smoothing", smoothingEnabled ? "1" : "0"); if (smoothingEnabled) { if (historySize > 0) { JoyButton::setMouseHistorySize(historySize, GlobalVariables::JoyButton::MAXIMUMMOUSEHISTORYSIZE, GlobalVariables::JoyButton::mouseHistorySize, &GlobalVariables::JoyButton::mouseHistoryX, &GlobalVariables::JoyButton::mouseHistoryY); } if (weightModifier != 0.0) { JoyButton::setWeightModifier(weightModifier, GlobalVariables::JoyButton::MAXIMUMWEIGHTMODIFIER, GlobalVariables::JoyButton::weightModifier); } } else { JoyButton::setMouseHistorySize( 1, GlobalVariables::JoyButton::MAXIMUMMOUSEHISTORYSIZE, GlobalVariables::JoyButton::mouseHistorySize, &GlobalVariables::JoyButton::mouseHistoryX, &GlobalVariables::JoyButton::mouseHistoryY); JoyButton::setWeightModifier(0.0, GlobalVariables::JoyButton::MAXIMUMWEIGHTMODIFIER, GlobalVariables::JoyButton::weightModifier); } if (historySize > 0) { settings->setValue("Mouse/HistorySize", historySize); } if (weightModifier > 0.0) { settings->setValue("Mouse/WeightModifier", weightModifier); } int refreshIndex = ui->mouseRefreshRateComboBox->currentIndex(); int mouseRefreshRate = ui->mouseRefreshRateComboBox->itemData(refreshIndex).toInt(); if (mouseRefreshRate != GlobalVariables::JoyButton::mouseRefreshRate) { settings->setValue("Mouse/RefreshRate", mouseRefreshRate); JoyButton::setMouseRefreshRate(mouseRefreshRate, GlobalVariables::JoyButton::mouseRefreshRate, GlobalVariables::JoyButton::IDLEMOUSEREFRESHRATE, JoyButton::getMouseHelper(), &GlobalVariables::JoyButton::mouseHistoryX, &GlobalVariables::JoyButton::mouseHistoryY, JoyButton::getTestOldMouseTime(), JoyButton::getStaticMouseEventTimer()); } int springIndex = ui->springScreenComboBox->currentIndex(); int springScreen = ui->springScreenComboBox->itemData(springIndex).toInt(); JoyButton::setSpringModeScreen(springScreen, GlobalVariables::JoyButton::springModeScreen); settings->setValue("Mouse/SpringScreen", QString::number(springScreen)); int pollIndex = ui->gamepadPollRateComboBox->currentIndex(); int gamepadPollRate = ui->gamepadPollRateComboBox->itemData(pollIndex).toInt(); if (gamepadPollRate != GlobalVariables::JoyButton::gamepadRefreshRate) { JoyButton::setGamepadRefreshRate(gamepadPollRate, GlobalVariables::JoyButton::gamepadRefreshRate, JoyButton::getMouseHelper()); settings->setValue("GamepadPollRate", QString::number(gamepadPollRate)); } // Advanced Tab settings->setValue("LogFile", ui->logFilePathEdit->text()); int logLevel = ui->logLevelComboBox->currentIndex(); if (logLevel < 0) { logLevel = 0; } if (Logger::LOG_MAX < logLevel) { logLevel = Logger::LOG_MAX; } settings->setValue("LogLevel", logLevel); // End Advanced Tab PadderCommon::unlockInputDevices(); settings->sync(); settings->getLock()->unlock(); } void MainSettingsDialog::selectDefaultProfileDir() { QString lookupDir = PadderCommon::preferredProfileDir(settings); QString directory = QFileDialog::getExistingDirectory(this, tr("Select Default Profile Directory"), lookupDir); if (!directory.isEmpty() && QFileInfo(directory).exists()) { ui->profileDefaultDirLineEdit->setText(directory); } } void MainSettingsDialog::checkLocaleChange() { settings->getLock()->lock(); int row = ui->localeListWidget->currentRow(); if (row == 0) { if (settings->contains("Language")) { settings->remove("Language"); } settings->getLock()->unlock(); emit changeLanguage(QLocale::system().name()); } else { QString newLocale = "en"; switch (row) { case 1: { newLocale = "br"; break; } case 2: { newLocale = "en"; break; } case 3: { newLocale = "fr"; break; } case 4: { newLocale = "de"; break; } case 5: { newLocale = "it"; break; } case 6: { newLocale = "ja"; break; } case 7: { newLocale = "ru"; break; } case 8: { newLocale = "sr"; break; } case 9: { newLocale = "zh_CN"; break; } case 10: { newLocale = "es"; break; } case 11: { newLocale = "uk"; break; } case 12: { newLocale = "pl"; break; } } settings->setValue("Language", newLocale); settings->getLock()->unlock(); emit changeLanguage(newLocale); } } void MainSettingsDialog::populateAutoProfiles() { exeAutoProfiles.clear(); defaultAutoProfiles.clear(); settings->beginGroup("DefaultAutoProfiles"); QStringList registeredGUIDs = settings->value("Uniques", QStringList()).toStringList(); settings->endGroup(); QString allProfile = settings->value(QString("DefaultAutoProfileAll/Profile"), "all").toString(); QString allActive = settings->value(QString("DefaultAutoProfileAll/Active"), "0").toString(); QString partialTitle = settings->value(QString("DefaultAutoProfileAll/PartialTitle"), "").toString(); bool defaultActive = allActive == "1" ? true : false; bool partialTitleBool = partialTitle == "1" ? true : false; allDefaultProfile = new AutoProfileInfo("all", allProfile, defaultActive, partialTitleBool, this); allDefaultProfile->setDefaultState(true); QStringListIterator iter(registeredGUIDs); while (iter.hasNext()) { QString tempkey = iter.next(); QString guid = tempkey; QString profile = settings->value(QString("DefaultAutoProfile-%1/Profile").arg(guid), "").toString(); QString active = settings->value(QString("DefaultAutoProfile-%1/Active").arg(guid), "0").toString(); QString partialTitle = settings->value(QString("DefaultAutoProfile-%1/PartialTitle").arg(guid), "0").toString(); bool partialTitleBool = partialTitle == "1" ? true : false; QString deviceName = settings->value(QString("DefaultAutoProfile-%1/DeviceName").arg(guid), "").toString(); QString windowClass = settings->value(QString("DefaultAutoProfile-%1/WindowClass").arg(guid), "").toString(); QString windowName = settings->value(QString("DefaultAutoProfile-%1/WindowName").arg(guid), "").toString(); QString exe = settings->value(QString("DefaultAutoProfile-%1/Exe").arg(guid), "").toString(); if (!guid.isEmpty() && !profile.isEmpty() && !deviceName.isEmpty()) { bool profileActive = active == "1" ? true : false; if (!defaultAutoProfiles.contains(guid) && guid != "all") { AutoProfileInfo *info = new AutoProfileInfo(guid, profile, profileActive, partialTitleBool, this); info->setDefaultState(true); info->setDeviceName(deviceName); info->setExe(exe); info->setWindowName(windowName); info->setWindowClass(windowClass); defaultAutoProfiles.insert(guid, info); defaultList.append(info); QList templist; templist.append(info); deviceAutoProfiles.insert(guid, templist); } } } settings->beginGroup("AutoProfiles"); bool quitSearch = false; for (int i = 1; !quitSearch; i++) { QString exe = settings->value(QString("AutoProfile%1Exe").arg(i), "").toString(); QString windowName = settings->value(QString("AutoProfile%1WindowName").arg(i), "").toString(); QString windowClass = settings->value(QString("AutoProfile%1WindowClass").arg(i), "").toString(); convToUniqueIDAutoProfGroupSett(settings, QString("AutoProfile%1GUID").arg(i), QString("AutoProfile%1UniqueID").arg(i)); QString guid = settings->value(QString("AutoProfile%1UniqueID").arg(i), "").toString(); QString profile = settings->value(QString("AutoProfile%1Profile").arg(i), "").toString(); QString active = settings->value(QString("AutoProfile%1Active").arg(i), 0).toString(); QString partialTitle = settings->value(QString("AutoProfile%1PartialTitle").arg(i), 0).toString(); bool partialTitleBool = partialTitle == "1" ? true : false; QString deviceName = settings->value(QString("AutoProfile%1DeviceName").arg(i), "").toString(); // Check if all required elements exist. If not, assume that the end of the // list has been reached. if ((!exe.isEmpty() || !windowClass.isEmpty() || !windowName.isEmpty()) && !guid.isEmpty()) { bool profileActive = active == "1" ? true : false; AutoProfileInfo *info = new AutoProfileInfo(guid, profile, exe, profileActive, partialTitleBool, this); if (!deviceName.isEmpty()) { info->setDeviceName(deviceName); } info->setWindowName(windowName); info->setWindowClass(windowClass); profileList.append(info); QList templist; if (guid != "all") { if (deviceAutoProfiles.contains(guid)) { templist = deviceAutoProfiles.value(guid); } templist.append(info); deviceAutoProfiles.insert(guid, templist); } } else { quitSearch = true; } } settings->endGroup(); } void MainSettingsDialog::fillAutoProfilesTable(QString guid) { for (int i = ui->autoProfileTableWidget->rowCount() - 1; i >= 0; i--) { ui->autoProfileTableWidget->removeRow(i); } ui->autoProfileTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); if (defaultAutoProfiles.contains(guid) || deviceAutoProfiles.contains(guid)) { int i = 0; AutoProfileInfo *defaultForGUID = nullptr; if (defaultAutoProfiles.contains(guid)) { AutoProfileInfo *info = defaultAutoProfiles.value(guid); defaultForGUID = info; ui->autoProfileTableWidget->insertRow(i); QTableWidgetItem *item = new QTableWidgetItem(); item->setCheckState(info->isActive() ? Qt::Checked : Qt::Unchecked); ui->autoProfileTableWidget->setItem(i, 0, item); QString deviceName = info->getDeviceName(); QString guidDisplay = info->getUniqueID(); if (!deviceName.isEmpty()) { guidDisplay = QString("%1 ").arg(info->getDeviceName()); guidDisplay.append(QString("(%1)").arg(info->getUniqueID())); } item = new QTableWidgetItem(guidDisplay); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getUniqueID()); item->setToolTip(info->getUniqueID()); ui->autoProfileTableWidget->setItem(i, 1, item); QFileInfo profilePath(info->getProfileLocation()); item = new QTableWidgetItem(profilePath.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getProfileLocation()); item->setToolTip(info->getProfileLocation()); ui->autoProfileTableWidget->setItem(i, 2, item); item = new QTableWidgetItem(info->getWindowClass()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getWindowClass()); item->setToolTip(info->getWindowClass()); ui->autoProfileTableWidget->setItem(i, 3, item); item = new QTableWidgetItem(info->getWindowName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getWindowName()); item->setToolTip(info->getWindowName()); ui->autoProfileTableWidget->setItem(i, 4, item); QFileInfo exeInfo(info->getExe()); item = new QTableWidgetItem(exeInfo.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getExe()); item->setToolTip(info->getExe()); ui->autoProfileTableWidget->setItem(i, 5, item); item = new QTableWidgetItem("Default"); item->setData(Qt::UserRole, "default"); ui->autoProfileTableWidget->setItem(i, 6, item); item = new QTableWidgetItem("Instance"); item->setData(Qt::UserRole, QVariant::fromValue(info)); ui->autoProfileTableWidget->setItem(i, 7, item); i++; } QListIterator iter(deviceAutoProfiles.value(guid)); while (iter.hasNext()) { AutoProfileInfo *info = iter.next(); if (!defaultForGUID || info != defaultForGUID) { ui->autoProfileTableWidget->insertRow(i); QTableWidgetItem *item = new QTableWidgetItem(); item->setCheckState(info->isActive() ? Qt::Checked : Qt::Unchecked); ui->autoProfileTableWidget->setItem(i, 0, item); QString deviceName = info->getDeviceName(); QString guidDisplay = info->getUniqueID(); if (!deviceName.isEmpty()) { guidDisplay = QString("%1 ").arg(info->getDeviceName()); guidDisplay.append(QString("(%1)").arg(info->getUniqueID())); } item = new QTableWidgetItem(guidDisplay); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getUniqueID()); item->setToolTip(info->getUniqueID()); ui->autoProfileTableWidget->setItem(i, 1, item); QFileInfo profilePath(info->getProfileLocation()); item = new QTableWidgetItem(profilePath.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getProfileLocation()); item->setToolTip(info->getProfileLocation()); ui->autoProfileTableWidget->setItem(i, 2, item); // nie są wstawiane wartości jeśli !deviceName.isEmpty(), więc jest inne niż all i jeśli jest default item = new QTableWidgetItem(info->getWindowClass()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getWindowClass()); item->setToolTip(info->getWindowClass()); ui->autoProfileTableWidget->setItem(i, 3, item); // nie są wstawiane wartości jeśli !deviceName.isEmpty(), więc jest inne niż all i jeśli jest default item = new QTableWidgetItem(info->getWindowName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getWindowName()); item->setToolTip(info->getWindowName()); ui->autoProfileTableWidget->setItem(i, 4, item); // nie są wstawiane wartości jeśli !deviceName.isEmpty(), więc jest inne niż all i jeśli jest default QFileInfo exeInfo(info->getExe()); item = new QTableWidgetItem(exeInfo.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getExe()); item->setToolTip(info->getExe()); ui->autoProfileTableWidget->setItem(i, 5, item); item = new QTableWidgetItem("Instance"); item->setData(Qt::UserRole, QVariant::fromValue(info)); ui->autoProfileTableWidget->setItem(i, 7, item); i++; } } } } void MainSettingsDialog::clearAutoProfileData() {} void MainSettingsDialog::fillGUIDComboBox() { ui->devicesComboBox->clear(); ui->devicesComboBox->addItem(tr("All"), QVariant("all")); QList guids = deviceAutoProfiles.keys(); QListIterator iter(guids); while (iter.hasNext()) { QString guid = iter.next(); QList temp = deviceAutoProfiles.value(guid); if (temp.count() > 0) { QString deviceName = temp.first()->getDeviceName(); if (!deviceName.isEmpty()) { ui->devicesComboBox->addItem(deviceName, QVariant(guid)); } else { ui->devicesComboBox->addItem(guid, QVariant(guid)); } } else { ui->devicesComboBox->addItem(guid, QVariant(guid)); } } } void MainSettingsDialog::changeDeviceForProfileTable(int index) { disconnect(ui->autoProfileTableWidget, &QTableWidget::itemChanged, this, &MainSettingsDialog::processAutoProfileActiveClick); if (index == 0) { fillAllAutoProfilesTable(); } else { QString guid = ui->devicesComboBox->itemData(index).toString(); fillAutoProfilesTable(guid); } connect(ui->autoProfileTableWidget, &QTableWidget::itemChanged, this, &MainSettingsDialog::processAutoProfileActiveClick); } void MainSettingsDialog::saveAutoProfileSettings() { settings->getLock()->lock(); settings->beginGroup("DefaultAutoProfiles"); QStringList defaultkeys = settings->allKeys(); settings->endGroup(); QStringListIterator iterDefaults(defaultkeys); while (iterDefaults.hasNext()) { QString tempkey = iterDefaults.next(); QString guid = QString(tempkey).replace("UniqueID", ""); QString testkey = QString("DefaultAutoProfile-%1").arg(guid); settings->beginGroup(testkey); settings->remove(""); settings->endGroup(); } settings->beginGroup("DefaultAutoProfiles"); settings->remove(""); settings->endGroup(); settings->beginGroup("DefaultAutoProfileAll"); settings->remove(""); settings->endGroup(); settings->beginGroup("AutoProfiles"); settings->remove(""); settings->endGroup(); if (allDefaultProfile) { QString profile = allDefaultProfile->getProfileLocation(); QString defaultActive = allDefaultProfile->isActive() ? "1" : "0"; settings->setValue(QString("DefaultAutoProfileAll/Profile"), profile); settings->setValue(QString("DefaultAutoProfileAll/Active"), defaultActive); } QMapIterator iter(defaultAutoProfiles); QStringList registeredGUIDs = QStringList(); while (iter.hasNext()) { iter.next(); QString guid = iter.key(); registeredGUIDs.append(guid); AutoProfileInfo *info = iter.value(); QString profileActive = info->isActive() ? "1" : "0"; QString deviceName = info->getDeviceName(); settings->setValue(QString("DefaultAutoProfiles/UniqueID%1").arg(guid), guid); settings->setValue(QString("DefaultAutoProfile-%1/Profile").arg(guid), info->getProfileLocation()); settings->setValue(QString("DefaultAutoProfile-%1/Active").arg(guid), profileActive); settings->setValue(QString("DefaultAutoProfile-%1/DeviceName").arg(guid), deviceName); settings->setValue(QString("DefaultAutoProfile-%1/WindowName").arg(guid), info->getWindowName()); settings->setValue(QString("DefaultAutoProfile-%1/WindowClass").arg(guid), info->getWindowClass()); settings->setValue(QString("DefaultAutoProfile-%1/Exe").arg(guid), info->getExe()); settings->setValue(QString("DefaultAutoProfile-%1/PartialTitle").arg(guid), 0); } if (!registeredGUIDs.isEmpty()) settings->setValue("DefaultAutoProfiles/Uniques", registeredGUIDs); settings->beginGroup("AutoProfiles"); QString autoActive = ui->activeCheckBox->isChecked() ? "1" : "0"; settings->setValue("AutoProfilesActive", autoActive); QListIterator iterProfiles(profileList); int i = 1; while (iterProfiles.hasNext()) { AutoProfileInfo *info = iterProfiles.next(); QString defaultActive = info->isActive() ? "1" : "0"; QString partialTitle = info->isPartialState() ? "1" : "0"; if (!info->getExe().isEmpty()) { settings->setValue(QString("AutoProfile%1Exe").arg(i), info->getExe()); } if (!info->getWindowClass().isEmpty()) { settings->setValue(QString("AutoProfile%1WindowClass").arg(i), info->getWindowClass()); } if (!info->getWindowName().isEmpty()) { settings->setValue(QString("AutoProfile%1WindowName").arg(i), info->getWindowName()); } convToUniqueIDAutoProfGroupSett(settings, QString("AutoProfile%1GUID").arg(i), QString("AutoProfile%1UniqueID").arg(i)); settings->setValue(QString("AutoProfile%1UniqueID").arg(i), info->getUniqueID()); settings->setValue(QString("AutoProfile%1Profile").arg(i), info->getProfileLocation()); settings->setValue(QString("AutoProfile%1Active").arg(i), defaultActive); settings->setValue(QString("AutoProfile%1PartialTitle").arg(i), partialTitle); settings->setValue(QString("AutoProfile%1DeviceName").arg(i), info->getDeviceName()); i++; } settings->endGroup(); settings->getLock()->unlock(); } void MainSettingsDialog::fillAllAutoProfilesTable() { for (int i = ui->autoProfileTableWidget->rowCount() - 1; i >= 0; i--) { ui->autoProfileTableWidget->removeRow(i); } ui->autoProfileTableWidget->horizontalHeader()->setVisible(true); ui->autoProfileTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); ui->autoProfileTableWidget->hideColumn(7); int i = 0; AutoProfileInfo *info = allDefaultProfile; ui->autoProfileTableWidget->insertRow(i); QTableWidgetItem *item = new QTableWidgetItem(); item->setCheckState(info->isActive() ? Qt::Checked : Qt::Unchecked); ui->autoProfileTableWidget->setItem(i, 0, item); QString deviceName = info->getDeviceName(); QString guidDisplay = info->getUniqueID(); if (!deviceName.isEmpty()) { guidDisplay = QString("%1 ").arg(info->getDeviceName()); guidDisplay.append(QString("(%1)").arg(info->getUniqueID())); } item = new QTableWidgetItem(guidDisplay); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getUniqueID()); item->setToolTip(info->getUniqueID()); ui->autoProfileTableWidget->setItem(i, 1, item); QFileInfo profilePath(info->getProfileLocation()); item = new QTableWidgetItem(profilePath.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getProfileLocation()); item->setToolTip(info->getProfileLocation()); ui->autoProfileTableWidget->setItem(i, 2, item); QFileInfo exeInfo(info->getExe()); item = new QTableWidgetItem(exeInfo.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getExe()); item->setToolTip(info->getExe()); ui->autoProfileTableWidget->setItem(i, 5, item); item = new QTableWidgetItem("Default"); item->setData(Qt::UserRole, "default"); ui->autoProfileTableWidget->setItem(i, 6, item); item = new QTableWidgetItem("Instance"); item->setData(Qt::UserRole, QVariant::fromValue(info)); ui->autoProfileTableWidget->setItem(i, 7, item); i++; QListIterator iterDefaults(defaultList); while (iterDefaults.hasNext()) { AutoProfileInfo *info = iterDefaults.next(); ui->autoProfileTableWidget->insertRow(i); QTableWidgetItem *item = new QTableWidgetItem(); item->setCheckState(info->isActive() ? Qt::Checked : Qt::Unchecked); ui->autoProfileTableWidget->setItem(i, 0, item); QString deviceName = info->getDeviceName(); QString guidDisplay = info->getUniqueID(); if (!deviceName.isEmpty()) { guidDisplay = QString("%1 ").arg(info->getDeviceName()); guidDisplay.append(QString("(%1)").arg(info->getUniqueID())); } item = new QTableWidgetItem(guidDisplay); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getUniqueID()); item->setToolTip(info->getUniqueID()); ui->autoProfileTableWidget->setItem(i, 1, item); QFileInfo profilePath(info->getProfileLocation()); item = new QTableWidgetItem(profilePath.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getProfileLocation()); item->setToolTip(info->getProfileLocation()); ui->autoProfileTableWidget->setItem(i, 2, item); item = new QTableWidgetItem(info->getWindowClass()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getWindowClass()); item->setToolTip(info->getWindowClass()); ui->autoProfileTableWidget->setItem(i, 3, item); item = new QTableWidgetItem(info->getWindowName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getWindowName()); item->setToolTip(info->getWindowName()); ui->autoProfileTableWidget->setItem(i, 4, item); QFileInfo exeInfo(info->getExe()); item = new QTableWidgetItem(exeInfo.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getExe()); item->setToolTip(info->getExe()); ui->autoProfileTableWidget->setItem(i, 5, item); item = new QTableWidgetItem("Default"); item->setData(Qt::UserRole, "default"); ui->autoProfileTableWidget->setItem(i, 6, item); item = new QTableWidgetItem("Instance"); item->setData(Qt::UserRole, QVariant::fromValue(info)); ui->autoProfileTableWidget->setItem(i, 7, item); i++; } QListIterator iter(profileList); while (iter.hasNext()) { AutoProfileInfo *info = iter.next(); ui->autoProfileTableWidget->insertRow(i); QTableWidgetItem *item = new QTableWidgetItem(); item->setCheckState(info->isActive() ? Qt::Checked : Qt::Unchecked); ui->autoProfileTableWidget->setItem(i, 0, item); QString deviceName = info->getDeviceName(); QString guidDisplay = info->getUniqueID(); if (!deviceName.isEmpty()) { guidDisplay = QString("%1 ").arg(info->getDeviceName()); guidDisplay.append(QString("(%1)").arg(info->getUniqueID())); } item = new QTableWidgetItem(guidDisplay); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getUniqueID()); item->setToolTip(info->getUniqueID()); ui->autoProfileTableWidget->setItem(i, 1, item); QFileInfo profilePath(info->getProfileLocation()); item = new QTableWidgetItem(profilePath.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getProfileLocation()); item->setToolTip(info->getProfileLocation()); ui->autoProfileTableWidget->setItem(i, 2, item); item = new QTableWidgetItem(info->getWindowClass()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getWindowClass()); item->setToolTip(info->getWindowClass()); ui->autoProfileTableWidget->setItem(i, 3, item); item = new QTableWidgetItem(info->getWindowName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getWindowName()); item->setToolTip(info->getWindowName()); ui->autoProfileTableWidget->setItem(i, 4, item); QFileInfo exeInfo(info->getExe()); item = new QTableWidgetItem(exeInfo.fileName()); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getExe()); item->setToolTip(info->getExe()); ui->autoProfileTableWidget->setItem(i, 5, item); item = new QTableWidgetItem(); item->setData(Qt::UserRole, ""); ui->autoProfileTableWidget->setItem(i, 6, item); item = new QTableWidgetItem("Instance"); item->setData(Qt::UserRole, QVariant::fromValue(info)); ui->autoProfileTableWidget->setItem(i, 7, item); i++; } } void MainSettingsDialog::processAutoProfileActiveClick(QTableWidgetItem *item) { if (item && (item->column() == 0)) { QTableWidgetItem *infoitem = ui->autoProfileTableWidget->item(item->row(), 7); AutoProfileInfo *info = infoitem->data(Qt::UserRole).value(); Qt::CheckState active = item->checkState(); if (active == Qt::Unchecked) { info->setActive(false); } else if (active == Qt::Checked) { info->setActive(true); } } } void MainSettingsDialog::openAddAutoProfileDialog() { QList reservedGUIDs = defaultAutoProfiles.keys(); AutoProfileInfo *info = new AutoProfileInfo(this); AddEditAutoProfileDialog *dialog = new AddEditAutoProfileDialog(info, settings, connectedDevices, reservedGUIDs, false, this); connect(dialog, &AddEditAutoProfileDialog::accepted, this, [this, dialog] { addNewAutoProfile(dialog); }); connect(dialog, &AddEditAutoProfileDialog::rejected, info, &AutoProfileInfo::deleteLater); dialog->show(); } void MainSettingsDialog::openEditAutoProfileDialog() { int selectedRow = ui->autoProfileTableWidget->currentRow(); if (selectedRow >= 0) { QTableWidgetItem *item = ui->autoProfileTableWidget->item(selectedRow, 7); AutoProfileInfo *info = item->data(Qt::UserRole).value(); if (info != allDefaultProfile) { QList reservedGUIDs = defaultAutoProfiles.keys(); if (info->getUniqueID() != "all") { AutoProfileInfo *temp = defaultAutoProfiles.value(info->getUniqueID()); if (info == temp) { reservedGUIDs.removeAll(info->getUniqueID()); } } QTableWidgetItem *itemDefault = ui->autoProfileTableWidget->item(selectedRow, 6); if (itemDefault->data(Qt::UserRole) == "default" || itemDefault->text() == "Default") info->setDefaultState(true); AddEditAutoProfileDialog *dialog = new AddEditAutoProfileDialog(info, settings, connectedDevices, reservedGUIDs, true, this); connect(dialog, &AddEditAutoProfileDialog::accepted, this, [this, dialog] { transferEditsToCurrentTableRow(dialog); }); dialog->show(); } else { info->setDefaultState(true); EditAllDefaultAutoProfileDialog *dialog = new EditAllDefaultAutoProfileDialog(info, settings, this); dialog->show(); connect(dialog, &EditAllDefaultAutoProfileDialog::accepted, this, [this, dialog] { transferAllProfileEditToCurrentTableRow(dialog); }); } } } void MainSettingsDialog::openDeleteAutoProfileConfirmDialog() { QMessageBox msgBox; msgBox.setText(tr("Are you sure you want to delete the profile?")); msgBox.setStandardButtons(QMessageBox::Discard | QMessageBox::Cancel); msgBox.setDefaultButton(QMessageBox::Cancel); int ret = msgBox.exec(); if (ret == QMessageBox::Discard) { int selectedRow = ui->autoProfileTableWidget->currentRow(); if (selectedRow >= 0) { QTableWidgetItem *item = ui->autoProfileTableWidget->item(selectedRow, 7); AutoProfileInfo *info = item->data(Qt::UserRole).value(); if (info->isCurrentDefault()) { if (info->getUniqueID() == "all") { allDefaultProfile->deleteLater(); allDefaultProfile = nullptr; } else if (defaultAutoProfiles.contains(info->getUniqueID())) { defaultAutoProfiles.remove(info->getUniqueID()); defaultList.removeAll(info); delete info; info = nullptr; } } else { if (deviceAutoProfiles.contains(info->getUniqueID())) { QList temp = deviceAutoProfiles.value(info->getUniqueID()); temp.removeAll(info); deviceAutoProfiles.insert(info->getUniqueID(), temp); } profileList.removeAll(info); delete info; info = nullptr; } } ui->autoProfileTableWidget->removeRow(selectedRow); } } void MainSettingsDialog::changeAutoProfileButtonsState() { int selectedRow = ui->autoProfileTableWidget->currentRow(); if (selectedRow >= 0) { QTableWidgetItem *item = ui->autoProfileTableWidget->item(selectedRow, 7); AutoProfileInfo *info = item->data(Qt::UserRole).value(); if (info == allDefaultProfile) { ui->autoProfileAddPushButton->setEnabled(true); ui->autoProfileEditPushButton->setEnabled(true); ui->autoProfileDeletePushButton->setEnabled(false); } else { ui->autoProfileAddPushButton->setEnabled(true); ui->autoProfileEditPushButton->setEnabled(true); ui->autoProfileDeletePushButton->setEnabled(true); } } else { ui->autoProfileAddPushButton->setEnabled(true); ui->autoProfileDeletePushButton->setEnabled(false); ui->autoProfileEditPushButton->setEnabled(false); } } void MainSettingsDialog::transferAllProfileEditToCurrentTableRow(EditAllDefaultAutoProfileDialog *dialog) { AutoProfileInfo *info = dialog->getAutoProfile(); allDefaultProfile = info; changeDeviceForProfileTable(0); } void MainSettingsDialog::transferEditsToCurrentTableRow(AddEditAutoProfileDialog *dialog) { AutoProfileInfo *info = dialog->getAutoProfile(); // Delete pointers to object that might be misplaced // due to an association change. QString oldGUID = dialog->getOriginalUniqueID(); if (oldGUID != info->getUniqueID()) { if (defaultAutoProfiles.value(oldGUID) == info) { defaultAutoProfiles.remove(oldGUID); } if (info->isCurrentDefault()) { defaultAutoProfiles.insert(info->getUniqueID(), info); } } if ((oldGUID != info->getUniqueID()) && deviceAutoProfiles.contains(oldGUID)) { QList temp = deviceAutoProfiles.value(oldGUID); temp.removeAll(info); if (temp.count() > 0) { deviceAutoProfiles.insert(oldGUID, temp); } else { deviceAutoProfiles.remove(oldGUID); } if (deviceAutoProfiles.contains(info->getUniqueID())) { QList temp2 = deviceAutoProfiles.value(oldGUID); if (!temp2.contains(info)) { temp2.append(info); deviceAutoProfiles.insert(info->getUniqueID(), temp2); } } else if (info->getUniqueID().toLower() != "all") { QList temp2; temp2.append(info); deviceAutoProfiles.insert(info->getUniqueID(), temp2); } } else if ((oldGUID != info->getUniqueID()) && (info->getUniqueID().toLower() != "all")) { QList temp; temp.append(info); deviceAutoProfiles.insert(info->getUniqueID(), temp); } if (!info->isCurrentDefault()) { defaultList.removeAll(info); if (!profileList.contains(info)) { profileList.append(info); } } else { profileList.removeAll(info); if (!defaultList.contains(info)) { defaultList.append(info); } } if (deviceAutoProfiles.contains(info->getUniqueID())) { QList temp2 = deviceAutoProfiles.value(info->getUniqueID()); if (!temp2.contains(info)) { temp2.append(info); deviceAutoProfiles.insert(info->getUniqueID(), temp2); } } else { QList temp2; temp2.append(info); deviceAutoProfiles.insert(info->getUniqueID(), temp2); } fillGUIDComboBox(); int currentIndex = ui->devicesComboBox->currentIndex(); changeDeviceForProfileTable(currentIndex); } void MainSettingsDialog::addNewAutoProfile(AddEditAutoProfileDialog *dialog) { // AddEditAutoProfileDialog *dialog = static_cast(sender()); AutoProfileInfo *info = dialog->getAutoProfile(); if (info->isCurrentDefault() && defaultAutoProfiles.contains(info->getUniqueID())) { WARN() << "Unable to add autoprofile with ID:" << info->getUniqueID() << " because it already exists and belongs to default autoprofiles"; return; } if (info->isCurrentDefault()) { if (!info->getUniqueID().isEmpty() && !info->getExe().isEmpty()) { defaultAutoProfiles.insert(info->getUniqueID(), info); defaultList.append(info); } } else { if (!info->getUniqueID().isEmpty() || !info->getExe().isEmpty()) { profileList.append(info); if (info->getUniqueID() != "all") { QList tempDevProfileList; if (deviceAutoProfiles.contains(info->getUniqueID())) tempDevProfileList = deviceAutoProfiles.value(info->getUniqueID()); tempDevProfileList.append(info); deviceAutoProfiles.insert(info->getUniqueID(), tempDevProfileList); } } else { WARN() << "Unable to add because neither ID, nor Executable is defined"; } } fillGUIDComboBox(); changeDeviceForProfileTable(ui->devicesComboBox->currentIndex()); INFO() << "Successfully added auto profile: " << info->toString(); } void MainSettingsDialog::autoProfileButtonsActiveState(bool enabled) { if (enabled) { changeAutoProfileButtonsState(); } else { ui->autoProfileAddPushButton->setEnabled(false); ui->autoProfileEditPushButton->setEnabled(false); ui->autoProfileDeletePushButton->setEnabled(false); } } void MainSettingsDialog::changeKeyRepeatWidgetsStatus(bool enabled) { ui->keyDelayHorizontalSlider->setEnabled(enabled); ui->keyDelaySpinBox->setEnabled(enabled); ui->keyRateHorizontalSlider->setEnabled(enabled); ui->keyRateSpinBox->setEnabled(enabled); } void MainSettingsDialog::checkSmoothingWidgetStatus(bool enabled) { if (enabled) { ui->historySizeSpinBox->setEnabled(true); ui->weightModifierDoubleSpinBox->setEnabled(true); } else { ui->historySizeSpinBox->setEnabled(false); ui->weightModifierDoubleSpinBox->setEnabled(false); } } void MainSettingsDialog::changePresetLanguage() { if (settings->contains("Language")) { QString targetLang = settings->value("Language").toString(); if (targetLang == "br") { ui->localeListWidget->setCurrentRow(1); } else if (targetLang == "en") { ui->localeListWidget->setCurrentRow(2); } else if (targetLang == "fr") { ui->localeListWidget->setCurrentRow(3); } else if (targetLang == "de") { ui->localeListWidget->setCurrentRow(4); } else if (targetLang == "it") { ui->localeListWidget->setCurrentRow(5); } else if (targetLang == "ja") { ui->localeListWidget->setCurrentRow(6); } else if (targetLang == "ru") { ui->localeListWidget->setCurrentRow(7); } else if (targetLang == "sr") { ui->localeListWidget->setCurrentRow(8); } else if (targetLang == "zh_CN") { ui->localeListWidget->setCurrentRow(9); } else if (targetLang == "es") { ui->localeListWidget->setCurrentRow(10); } else if (targetLang == "uk") { ui->localeListWidget->setCurrentRow(11); } else if (targetLang == "pl") { ui->localeListWidget->setCurrentRow(12); } else { ui->localeListWidget->setCurrentRow(0); } } else { ui->localeListWidget->setCurrentRow(0); } } void MainSettingsDialog::fillSpringScreenPresets() { ui->springScreenComboBox->clear(); ui->springScreenComboBox->addItem(tr("Default"), QVariant(GlobalVariables::AntimicroSettings::defaultSpringScreen)); for (int i = 0; i < QGuiApplication::screens().count(); i++) { ui->springScreenComboBox->addItem(QString(":%1").arg(i), QVariant(i)); } int screenIndex = ui->springScreenComboBox->findData(GlobalVariables::JoyButton::springModeScreen); if (screenIndex > -1) { ui->springScreenComboBox->setCurrentIndex(screenIndex); } } void MainSettingsDialog::refreshExtraMouseInfo() { #if defined(WITH_X11) QString handler = EventHandlerFactory::getInstance()->handler()->getIdentifier(); if (QApplication::platformName() == QStringLiteral("xcb")) { struct X11Extras::ptrInformation temp; if (handler == "uinput") { temp = X11Extras::getInstance()->getPointInformation(); } else if (handler == "xtest") { temp = X11Extras::getInstance()->getPointInformation(GlobalVariables::X11Extras::xtestMouseDeviceName); } if (temp.id >= 0) { ui->accelNumLabel->setText(QString::number(temp.accelNum)); ui->accelDenomLabel->setText(QString::number(temp.accelDenom)); ui->accelThresLabel->setText(QString::number(temp.threshold)); } } #endif } void MainSettingsDialog::resetMouseAcceleration() { #if defined(WITH_X11) if (QApplication::platformName() == QStringLiteral("xcb")) { X11Extras::getInstance()->x11ResetMouseAccelerationChange(); refreshExtraMouseInfo(); } #endif } void MainSettingsDialog::selectLogFile() { QString oldLogFile = settings->value("LogFile", "").toString(); QString newLogFile = QFileDialog::getSaveFileName(this, tr("Save Log File As"), oldLogFile, tr("Log Files (*.log)")); if (!newLogFile.isEmpty()) ui->logFilePathEdit->setText(newLogFile); } AntiMicroSettings *MainSettingsDialog::getSettings() const { return settings; } QMap *MainSettingsDialog::getDefaultAutoProfiles() { return &defaultAutoProfiles; } QMap> *MainSettingsDialog::getDeviceAutoProfiles() { return &deviceAutoProfiles; } QMap> *MainSettingsDialog::getExeAutoProfiles() { return &exeAutoProfiles; } QList *MainSettingsDialog::getDefaultList() { return &defaultList; } QList *MainSettingsDialog::getProfileList() { return &profileList; } AutoProfileInfo *MainSettingsDialog::getAllDefaultProfile() const { return allDefaultProfile; } QList *MainSettingsDialog::getConnectedDevices() const { return connectedDevices; } void MainSettingsDialog::on_resetBtn_clicked() { QMessageBox msgBox; msgBox.setText(tr("Do you really want to reset setting?")); msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); switch (msgBox.exec()) { case QMessageBox::Ok: resetGeneralSett(); resetAutoProfSett(); resetMouseSett(); resetAdvancedSett(); ui->localeListWidget->setCurrentRow(0); break; case QMessageBox::Cancel: break; default: break; } QMessageBox msgBox2; msgBox2.setText(tr("Would you like to reset mappings too?")); msgBox2.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); switch (msgBox2.exec()) { case QMessageBox::Ok: ui->controllerMappingsTableWidget->setRowCount(0); break; case QMessageBox::Cancel: break; default: break; } } void MainSettingsDialog::resetGeneralSett() { ui->profileDefaultDirLineEdit->setText(PadderCommon::preferredProfileDir(settings)); ui->numberRecentProfileSpinBox->setValue(5); int gamepadPollIndex = ui->gamepadPollRateComboBox->findData(GlobalVariables::JoyButton::gamepadRefreshRate); if (gamepadPollIndex >= 0) { ui->gamepadPollRateComboBox->setCurrentIndex(gamepadPollIndex); } ui->closeToTrayCheckBox->setChecked(false); ui->attachNumKeypadCheckbox->setChecked(false); ui->launchAtWinStartupCheckBox->setChecked(false); ui->traySingleProfileListCheckBox->setChecked(false); ui->minimizeTaskbarCheckBox->setChecked(false); ui->hideEmptyCheckBox->setChecked(false); ui->autoLoadPreviousCheckBox->setChecked(true); ui->launchInTrayCheckBox->setChecked(false); ui->associateProfilesCheckBox->setChecked(true); ui->keyRepeatEnableCheckBox->setChecked(false); ui->showLowBatteryNotification->setChecked(true); ui->showEmptyBatteryNotification->setChecked(true); ui->keyDelayHorizontalSlider->setValue(660); ui->keyRateHorizontalSlider->setValue(25); } void MainSettingsDialog::resetAutoProfSett() { disconnect(ui->autoProfileTableWidget, &QTableWidget::itemChanged, this, &MainSettingsDialog::processAutoProfileActiveClick); ui->activeCheckBox->setChecked(false); ui->devicesComboBox->setCurrentIndex(0); ui->autoProfileTableWidget->setRowCount(0); AutoProfileInfo *info = allDefaultProfile; ui->autoProfileTableWidget->insertRow(0); QTableWidgetItem *item = new QTableWidgetItem(); item->setCheckState(info->isActive() ? Qt::Checked : Qt::Unchecked); ui->autoProfileTableWidget->setItem(0, 0, item); QString deviceName = info->getDeviceName(); QString guidDisplay = info->getUniqueID(); if (!deviceName.isEmpty()) { guidDisplay = QString("%1 ").arg(info->getDeviceName()); guidDisplay.append(QString("(%1)").arg(info->getUniqueID())); } item = new QTableWidgetItem(guidDisplay); item->setFlags(item->flags() & ~Qt::ItemIsEditable); item->setData(Qt::UserRole, info->getUniqueID()); item->setToolTip(info->getUniqueID()); ui->autoProfileTableWidget->setItem(0, 1, item); item = new QTableWidgetItem("Default"); item->setData(Qt::UserRole, "default"); ui->autoProfileTableWidget->setItem(0, 6, item); item = new QTableWidgetItem("Instance"); item->setData(Qt::UserRole, QVariant::fromValue(info)); ui->autoProfileTableWidget->setItem(0, 7, item); if (ui->autoProfileTableWidget->rowCount() == 1) profileList.clear(); connect(ui->autoProfileTableWidget, &QTableWidget::itemChanged, this, &MainSettingsDialog::processAutoProfileActiveClick); } void MainSettingsDialog::resetMouseSett() { ui->disableWindowsEnhancedPointCheckBox->setChecked(false); ui->smoothingEnableCheckBox->setChecked(false); ui->smoothingEnableCheckBox->setEnabled(true); ui->historySizeSpinBox->setValue(10); ui->historySizeSpinBox->setEnabled(false); ui->weightModifierDoubleSpinBox->setValue(0.20); ui->weightModifierDoubleSpinBox->setEnabled(false); int refreshIndex = ui->mouseRefreshRateComboBox->findData(GlobalVariables::JoyButton::mouseRefreshRate); if (refreshIndex >= 0) { ui->mouseRefreshRateComboBox->setCurrentIndex(refreshIndex); } int screenIndex = ui->springScreenComboBox->findData(GlobalVariables::JoyButton::springModeScreen); if (screenIndex > -1) { ui->springScreenComboBox->setCurrentIndex(screenIndex); } } void MainSettingsDialog::resetAdvancedSett() { ui->logFilePathEdit->setText(""); ui->logLevelComboBox->setCurrentIndex(0); } void MainSettingsDialog::convToUniqueIDAutoProfGroupSett(QSettings *sett, QString guidAutoProfSett, QString uniqueAutoProfSett) { if (sett->contains(guidAutoProfSett)) { sett->setValue(uniqueAutoProfSett, sett->value(guidAutoProfSett)); sett->remove(guidAutoProfSett); } } AntiMicroX-antimicrox-b300273/src/gui/mainsettingsdialog.h000066400000000000000000000146541471077622000235750ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MAINSETTINGSDIALOG_H #define MAINSETTINGSDIALOG_H #include "ui_mainsettingsdialog.h" #include #include class AntiMicroSettings; class InputDevice; class QWidget; class AutoProfileInfo; class QTableWidgetItem; class EditAllDefaultAutoProfileDialog; class AddEditAutoProfileDialog; namespace Ui { class MainSettingsDialog; } class MainSettingsDialog : public QDialog { Q_OBJECT public: explicit MainSettingsDialog(AntiMicroSettings *settings, QList *devices, QWidget *parent = nullptr); ~MainSettingsDialog(); AntiMicroSettings *getSettings() const; QMap *getDefaultAutoProfiles(); // Default profiles assigned to a specific device QMap> * getDeviceAutoProfiles(); // Profiles assigned with an association with an application QMap> *getExeAutoProfiles(); QList *getDefaultList(); QList *getProfileList(); AutoProfileInfo *getAllDefaultProfile() const; QList *getConnectedDevices() const; protected: void fillControllerMappingsTable(); // MainSettingsMapping class void insertTempControllerMapping(QHash> &hash, QString newGUID); // MainSettingsMapping class void checkLocaleChange(); // MainSettingsLang class void populateAutoProfiles(); // MainSettingsProfile class void fillAutoProfilesTable(QString guid); // MainSettingsProfile class void fillAllAutoProfilesTable(); // MainSettingsProfile class void clearAutoProfileData(); // MainSettingsProfile class void changePresetLanguage(); // MainSettingsLang class void fillSpringScreenPresets(); // MainSettingsMouse class void refreshExtraMouseInfo(); // MainSettingsMouse class void convToUniqueIDAutoProfGroupSett(QSettings *sett, QString guidAutoProfSett, QString uniqueAutoProfSett); signals: void changeLanguage(QString language); // MainSettingsLang class protected slots: void mappingsTableItemChanged(QTableWidgetItem *item); // MainSettingsMapping class void insertMappingRow(); // MainSettingsMapping class void deleteMappingRow(); // MainSettingsMapping class void syncMappingSettings(); // MainSettingsMapping class void saveNewSettings(); void selectDefaultProfileDir(); // MainSettingsProfile class void fillGUIDComboBox(); // MainSettingsProfile class void changeDeviceForProfileTable(int index); // MainSettingsProfile class void saveAutoProfileSettings(); // MainSettingsProfile class void processAutoProfileActiveClick(QTableWidgetItem *item); // MainSettingsProfile class void openAddAutoProfileDialog(); // MainSettingsProfile class void openEditAutoProfileDialog(); // MainSettingsProfile class void openDeleteAutoProfileConfirmDialog(); // MainSettingsProfile class void changeAutoProfileButtonsState(); // MainSettingsProfile class void transferEditsToCurrentTableRow(AddEditAutoProfileDialog *dialog); // MainSettingsProfile class void transferAllProfileEditToCurrentTableRow(EditAllDefaultAutoProfileDialog *dialog); // MainSettingsProfile class void addNewAutoProfile(AddEditAutoProfileDialog *dialog); // MainSettingsProfile class void autoProfileButtonsActiveState(bool enabled); // MainSettingsProfile class void changeKeyRepeatWidgetsStatus(bool enabled); // MainSettingsProfile class void checkSmoothingWidgetStatus(bool enabled); // MainSettingsMouse class void resetMouseAcceleration(); // MainSettingsMouse class void selectLogFile(); // MainSettingsLogs class private slots: void on_resetBtn_clicked(); private: Ui::MainSettingsDialog *ui; AntiMicroSettings *settings; QMap defaultAutoProfiles; // Default profiles assigned to a specific device QMap> deviceAutoProfiles; // Profiles assigned with an association with an application QMap> exeAutoProfiles; QList defaultList; QList profileList; AutoProfileInfo *allDefaultProfile; QList *connectedDevices; void resetGeneralSett(); void resetAutoProfSett(); void resetMouseSett(); void resetAdvancedSett(); }; #endif // MAINSETTINGSDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/mainsettingsdialog.ui000066400000000000000000001444751471077622000237700ustar00rootroot00000000000000 MainSettingsDialog Qt::WindowModal 0 0 718 664 0 0 0 0 Edit Settings true 0 0 180 16777215 QListView::TopToBottom false QListView::Fixed false -1 General Controller Mappings Language Auto Profile Mouse Advanced 0 0 2 4 9 20 Pro&file Directory: profileDefaultDirLineEdit <html><head/><body><p>Specify the default directory that the program should use in file dialogs when loading a profile or saving a new profile.</p></body></html> 512 true false Recent Profile Count: <html><head/><body><p>Number of profiles that can be placed in recent profile list. 0 will result in the program not enforcing a limit on the number of profiles displayed.</p></body></html> 100 5 Qt::Vertical QSizePolicy::Fixed 20 8 8 Gamepad Poll Rate: Change the poll rate that the program uses to discover new events from gamepads. Defaults to 10 ms. Reducing the poll rate value could cause the application to use more CPU power so please test the setting that you use before using AntiMicroX unattended. Hide main window when the main window close button is clicked instead of quitting the program. Close To Tray Have Windows start AntiMicroX at system startup. Launch At Windows Startup Display recent profiles for all controllers as a single list in the tray menu. Defaults to using sub-menus. Single Profile List in Tray Have the program minimize to the taskbar. By default, the program minimizes to the system tray if available. Minimize to Taskbar This option will cause the program to hide all buttons that have no slots assigned to them. The Quick Set dialog window will have to be used to bring up the edit dialog for gamepad buttons. Hide Empty Buttons When the program is launched, open the last known profile that was opened during the previous session. Auto Load Last Opened Profile true Only show the system tray icon when the program first launches. Launch in Tray Associate .amgp files with AntiMicroX in Windows Explorer. Associate Profiles true Remember, it won't work if you don't have such keypad connected to computer or if it's not embedded like in desktop PCs -1 Attach the numeric keypad Show low battery notification Show empty battery notification Qt::Vertical QSizePolicy::Minimum 20 10 Key Repeat Active keys will be repeatedly pressed when this option is enabled. Enable Delay: false Specifies how much time should elapse before key repeating begins. 250 1000 10 100 660 Qt::Horizontal QSlider::NoTicks false ms 250 1000 100 660 Rate: false Specifies how many times key presses will be performed per seconds. 5 50 25 Qt::Horizontal QSlider::NoTicks false times/s 5 50 25 4 9 Below is a list of the custom mappings that have been saved. You can use the following table to delete mappings or have mappings temporarily disabled. You can also disable mappings that are included with SDL; just insert a new row with the appropriate joystick GUID and check disable. Settings will not take affect until you either refresh all joysticks or unplug that particular joystick. false true QAbstractItemView::SingleSelection true false 70 200 50 50 GUID Mapping String Disable? Add .. Delete .. 4 <html><head/><body><p>AntiMicroX has been translated into many different languages by contributors. By default, the program will choose an appropriate translation based on your system's locale setting. However, you can make AntiMicroX load a different translation depending on the language that you choose from the list below.</p></body></html> true Qt::Vertical QSizePolicy::Minimum 10 10 -1 Default Português do Brasil English Français Deutsch Italiano 日本語 Русский српски / srpski 简体中文 Español українська Polski You can help with translating AntiMicroX. Just click here: <a href="https://hosted.weblate.org/projects/antimicrox/">link</a> Qt::RichText true 4 Active 20 Qt::Horizontal 40 20 Devices: All Qt::Vertical QSizePolicy::Fixed 20 10 false QAbstractItemView::SingleSelection QAbstractItemView::SelectRows 8 false true 100 false true false Active Device Profile Class Title Program Default? Qt::Vertical QSizePolicy::Fixed 20 10 false Add .. false Edit .. false Delete .. 10 4 Disable the "Enhanced Pointer Precision" Windows setting while AntiMicroX is running. Disabling "Enhanced Pointer Precision" will allow mouse movement within AntiMicroX to be more precise. Disable Enhance Pointer Precision true Smoothing 10 20 Enable History Si&ze: historySizeSpinBox false 1 100 10 Weight Modi&fier: weightModifierDoubleSpinBox false 1.000000000000000 0.100000000000000 0.200000000000000 Refresh Rate: The refresh rate is the amount of time that will elapse in between mouse events. Please be cautious when editing this setting as it will cause the program to use more CPU power. Setting this value too low can cause system instability. Please test the setting before using it unattended. Spring 10 20 Screen: springScreenComboBox Utilize the specified screen for spring mode. On Linux, the default is to use the primary screen. On Windows, the default is to use all available screens. QFrame::StyledPanel QFrame::Raised 6 0 0 Accel Numerator: 0 0 0 Qt::Horizontal 40 20 Accel Denominator: 0 Qt::Horizontal 40 20 Accel Threshold: 0 Qt::Horizontal 40 20 Qt::Horizontal 40 20 If the acceleration values for the virtual mouse have been changed by a different process, particularly when quitting an older game, then you might want to reset the acceleration values used by the virtual mouse. Reset Acceleration Qt::Vertical 20 20 Qt::Vertical QSizePolicy::Minimum 20 10 QLayout::SetMinimumSize Log File: true <html><head/><body><p><span style=" font-style:italic;">Note Unspecified log file allows printing logs in console output</span></p></body></html> true true Qt::Vertical QSizePolicy::Minimum 20 10 QLayout::SetMinimumSize Qt::LeftToRight Log Level: 0 0 None Error Warning Info Verbose Debug Qt::Horizontal 40 20 Qt::Vertical QSizePolicy::Minimum 20 10 QLayout::SetMinimumSize 0 0 50 true false Note: To see the change of log level in console output (not in log file), application restart is required true Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true -1 Qt::Vertical 20 40 5 5 5 5 Reset Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() MainSettingsDialog accept() 248 254 157 274 buttonBox rejected() MainSettingsDialog reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/mainwindow.cpp000066400000000000000000001767211471077622000224230ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2022 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mainwindow.h" #include "ui_mainwindow.h" #include "aboutdialog.h" #include "antimicrosettings.h" #include "autoprofileinfo.h" #include "commandlineutility.h" #include "inputdevice.h" //#include "autoprofilewatcher.h" #include "advancestickassignmentdialog.h" #include "calibration.h" #include "common.h" #include "dpadpushbutton.h" #include "gamecontrollermappingdialog.h" #include "joyaxiswidget.h" #include "joybuttonwidget.h" #include "joycontrolstickbuttonpushbutton.h" #include "joycontrolstickpushbutton.h" #include "joydpadbuttonwidget.h" #include "joysensorpushbutton.h" #include "joystick.h" #include "joystickstatuswindow.h" #include "joytabwidget.h" #include "mainsettingsdialog.h" #include "qkeydisplaydialog.h" #include "xml/inputdevicexml.h" #include "xml/joybuttonslotxml.h" #if defined(WITH_X11) || defined(Q_OS_WIN) #include "autoprofileinfo.h" #include "autoprofilewatcher.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CHECK_FOR_UPDATES #include #include #endif #include #ifdef Q_OS_WIN #include "winextras.h" #include #endif #define CHECK_BATTERIES_MSEC 600000 MainWindow::MainWindow(QMap *joysticks, CommandLineUtility *cmdutility, AntiMicroSettings *settings, bool graphical, QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , trayIcon(nullptr) , trayIconMenu(nullptr) { ui->setupUi(this); setWindowIcon(PadderCommon::loadIcon("antimicrox", ":/images/antimicrox.png")); ui->stackedWidget->setCurrentIndex(0); m_translator = nullptr; m_appTranslator = nullptr; m_cmdutility = cmdutility; m_graphical = graphical; m_settings = settings; ui->actionStick_Pad_Assign->setVisible(false); #if defined(WITH_X11) if (QApplication::platformName() == QStringLiteral("xcb")) { this->appWatcher = new AutoProfileWatcher(settings, this); checkAutoProfileWatcherTimer(); } else { this->appWatcher = nullptr; qDebug() << "appWatcher instance set to null pointer"; } #elif defined(Q_OS_WIN) this->appWatcher = new AutoProfileWatcher(settings, this); checkAutoProfileWatcherTimer(); #else this->appWatcher = 0; #endif signalDisconnect = false; showTrayIcon = !cmdutility->isTrayHidden() && graphical && !cmdutility->shouldListControllers(); m_joysticks = joysticks; if (showTrayIcon) { trayIconMenu = new QMenu(this); trayIcon = new QSystemTrayIcon(this); trayIcon->setContextMenu(trayIconMenu); connect(trayIconMenu, &QMenu::aboutToShow, this, &MainWindow::refreshTrayIconMenu); connect(trayIcon, &QSystemTrayIcon::activated, this, &MainWindow::trayIconClickAction); } // Look at flags and call setEnabled as desired; defaults to true. // Enabled status is used to specify whether errors in profile loading and // saving should be display in a window or written to stderr. if (graphical) { if (cmdutility->isHiddenRequested() && cmdutility->isTrayHidden()) { setEnabled(false); } } else { setEnabled(false); } resize(settings->value("WindowSize", size()).toSize()); move(settings->value("WindowPosition", pos()).toPoint()); if (graphical) { aboutDialog = new AboutDialog(this); } else { aboutDialog = nullptr; } QMenu *menuPointer = ui->menuQuit; connect(ui->menuQuit, &QMenu::aboutToShow, this, [this, menuPointer] { mainMenuChange(menuPointer); }); QMenu *menuPointerOptions = ui->menuOptions; connect(ui->menuOptions, &QMenu::aboutToShow, this, [this, menuPointerOptions] { mainMenuChange(menuPointerOptions); }); connect(ui->actionKeyValue, &QAction::triggered, this, &MainWindow::openKeyCheckerDialog); connect(ui->actionAbout_Qt, &QAction::triggered, qApp, &QApplication::aboutQt); connect(ui->actionProperties, &QAction::triggered, this, &MainWindow::openJoystickStatusWindow); connect(ui->actionGitHubPage, &QAction::triggered, this, &MainWindow::openGitHubPage); connect(ui->actionIssues, &QAction::triggered, this, &MainWindow::openIssuesPage); connect(ui->actionOptions, &QAction::triggered, this, &MainWindow::openMainSettingsDialog); connect(ui->actionWiki, &QAction::triggered, this, &MainWindow::openWikiPage); connect(ui->actionCalibration, &QAction::triggered, this, &MainWindow::openCalibration); #if defined(WITH_X11) if (QApplication::platformName() == QStringLiteral("xcb")) { connect(appWatcher, &AutoProfileWatcher::foundApplicableProfile, this, &MainWindow::autoprofileLoad); } #elif defined(Q_OS_WIN) connect(appWatcher, &AutoProfileWatcher::foundApplicableProfile, this, &MainWindow::autoprofileLoad); #endif #ifdef Q_OS_WIN if (graphical) { if (!WinExtras::IsRunningAsAdmin()) { QIcon uacIcon = QApplication::style()->standardIcon(QStyle::SP_VistaShield); ui->uacPushButton->setIcon(uacIcon); connect(ui->uacPushButton, SIGNAL(clicked()), this, SLOT(restartAsElevated())); } else { ui->uacPushButton->setVisible(false); } } #else ui->uacPushButton->setVisible(false); #endif ui->updateButton->setVisible(false); #ifdef CHECK_FOR_UPDATES connect(&m_network_manager, &QNetworkAccessManager::finished, this, &MainWindow::networkManagerFinished); QNetworkRequest request(QUrl("https://api.github.com/repos/antimicrox/antimicrox/releases/latest")); m_network_manager.get(request); #endif bool notify_low = m_settings->value("Notifications/notify_about_low_battery", true).toBool(); bool notify_empty = m_settings->value("Notifications/notify_about_empty_battery", true).toBool(); if (notify_low || notify_empty) { QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, [this]() { this->checkEachTenMinutesBattery(m_joysticks); }); timer->start(CHECK_BATTERIES_MSEC); } } MainWindow::~MainWindow() { qDebug() << "removing main window"; if (trayIconMenu != nullptr) trayIconMenu->clear(); installEventFilter(trayIconMenu); installEventFilter(trayIcon); delete ui; } void MainWindow::alterConfigFromSettings() { if (m_cmdutility->shouldListControllers()) { m_graphical = false; } else if (m_cmdutility->hasProfile()) { if (m_cmdutility->hasControllerNumber()) { loadConfigFile(m_cmdutility->getProfileLocation(), m_cmdutility->getControllerNumber()); } else if (m_cmdutility->hasControllerID()) { loadConfigFile(m_cmdutility->getProfileLocation(), m_cmdutility->hasControllerID()); } else { loadConfigFile(m_cmdutility->getProfileLocation()); } } const QList tempList = m_cmdutility->getControllerOptionsList(); // unsigned int optionListSize = tempList->size(); QListIterator optionIter(tempList); while (optionIter.hasNext()) { ControllerOptionsInfo temp = optionIter.next(); if (temp.hasProfile()) { if (temp.hasControllerNumber()) { loadConfigFile(temp.getProfileLocation(), temp.getControllerNumber()); } else if (temp.hasControllerID()) { loadConfigFile(temp.getProfileLocation(), temp.hasControllerID()); } else { loadConfigFile(temp.getProfileLocation()); } } else if (temp.isUnloadRequested()) { if (temp.hasControllerNumber()) { unloadCurrentConfig(temp.getControllerNumber()); } else if (temp.hasControllerID()) { unloadCurrentConfig(temp.hasControllerID()); } else { unloadCurrentConfig(0); } } if (temp.getStartSetNumber() > 0) { if (temp.hasControllerNumber()) { changeStartSetNumber(temp.getJoyStartSetNumber(), temp.getControllerNumber()); } else if (temp.hasControllerID()) { changeStartSetNumber(temp.getJoyStartSetNumber(), temp.getControllerID()); } else { changeStartSetNumber(temp.getJoyStartSetNumber()); } } } } void MainWindow::fillButtons() { fillButtonsMap(m_joysticks); } void MainWindow::makeJoystickTabs() { ui->stackedWidget->setCurrentIndex(0); removeJoyTabs(); // Make temporary QMap with devices inserted using the device index as the // key rather than joystick ID. QMap temp; QMapIterator iterTemp(*m_joysticks); while (iterTemp.hasNext()) { iterTemp.next(); InputDevice *joystick = iterTemp.value(); temp.insert(joystick->getJoyNumber(), joystick); } QMapIterator iter(temp); while (iter.hasNext()) { iter.next(); InputDevice *joystick = iter.value(); JoyTabWidget *tabwidget = new JoyTabWidget(joystick, m_settings, this); QString joytabName = joystick->getSDLName(); joytabName.append(" ").append(tr("(%1)").arg(joystick->getName())); ui->tabWidget->addTab(tabwidget, joytabName); } if (m_joysticks != nullptr) { ui->tabWidget->setCurrentIndex(0); ui->stackedWidget->setCurrentIndex(1); } } void MainWindow::fillButtonsID(InputDevice *joystick) { int joyindex = joystick->getJoyNumber(); JoyTabWidget *tabwidget = qobject_cast(ui->tabWidget->widget(joyindex)); // static_cast tabwidget->refreshButtons(); } void MainWindow::fillButtonsMap(QMap *joysticks) { ui->stackedWidget->setCurrentIndex(0); removeJoyTabs(); // Make temporary QMap with devices inserted using the device index as the // key rather than joystick ID. QMap temp; QMapIterator iterTemp(*joysticks); while (iterTemp.hasNext()) { iterTemp.next(); InputDevice *joystick = iterTemp.value(); temp.insert(joystick->getJoyNumber(), joystick); } QMapIterator iter(temp); while (iter.hasNext()) { iter.next(); InputDevice *joystick = iter.value(); JoyTabWidget *tabwidget = new JoyTabWidget(joystick, m_settings, this); QString joytabName = joystick->getSDLName(); joytabName.append(" ").append(tr("(%1)").arg(joystick->getName())); ui->tabWidget->addTab(tabwidget, joytabName); tabwidget->refreshButtons(); connect(tabwidget, &JoyTabWidget::namesDisplayChanged, this, [this, tabwidget](bool displayNames) { propogateNameDisplayStatus(tabwidget, displayNames); }); connect(tabwidget, &JoyTabWidget::mappingUpdated, this, &MainWindow::propogateMappingUpdate); if (showTrayIcon) { connect(tabwidget, &JoyTabWidget::joystickConfigChanged, this, &MainWindow::populateTrayIcon); } } if (joysticks->size() > 0) { loadAppConfig(); ui->tabWidget->setCurrentIndex(0); ui->stackedWidget->setCurrentIndex(1); } if (showTrayIcon) { populateTrayIcon(); trayIcon->show(); } ui->actionUpdate_Joysticks->setEnabled(true); ui->actionHide->setEnabled(true); ui->actionQuit->setEnabled(true); } // Intermediate slot to be used in Form Designer void MainWindow::startJoystickRefresh() { ui->stackedWidget->setCurrentIndex(0); ui->actionUpdate_Joysticks->setEnabled(false); ui->actionHide->setEnabled(false); ui->actionQuit->setEnabled(false); removeJoyTabs(); emit joystickRefreshRequested(); } void MainWindow::populateTrayIcon() { disconnect(trayIconMenu, &QMenu::aboutToShow, this, &MainWindow::singleTrayProfileMenuShow); trayIconMenu->clear(); profileActions.clear(); closeAction = new QAction(tr("&Quit"), trayIconMenu); closeAction->setIcon(PadderCommon::loadIcon("application-exit", ":/images/actions/application_exit.png")); connect(closeAction, &QAction::triggered, this, &MainWindow::quitProgram, Qt::DirectConnection); hideAction = new QAction(tr("&Hide"), trayIconMenu); hideAction->setIcon(PadderCommon::loadIcon("view-restore", ":/images/actions/view_restore.png")); connect(hideAction, &QAction::triggered, this, &MainWindow::hideWindow); restoreAction = new QAction(tr("&Restore"), trayIconMenu); restoreAction->setIcon(PadderCommon::loadIcon("view-fullscreen", ":/images/actions/view_fullscreen.png")); connect(restoreAction, &QAction::triggered, this, &MainWindow::show); updateJoy = new QAction(tr("&Update Joysticks"), trayIconMenu); updateJoy->setIcon(PadderCommon::loadIcon("view-refresh", ":/images/actions/view_refresh.png")); connect(updateJoy, &QAction::triggered, this, &MainWindow::startJoystickRefresh); int joystickCount = m_joysticks->size(); qDebug() << "joystickCount: " << joystickCount; QMap uniques = QMap(); int counterUniques = 1; bool duplicatedGamepad = false; if (joystickCount > 0) { QMapIterator iter(*m_joysticks); bool useSingleList = m_settings->value("TrayProfileList", false).toBool(); qDebug() << "TrayProfileList: " << useSingleList; if (!useSingleList && (joystickCount == 1)) useSingleList = true; int i = 0; while (iter.hasNext()) { iter.next(); InputDevice *current = iter.value(); QString joytabName = current->getSDLName(); joytabName.append(" ").append(tr("(%1)").arg(current->getName())); qDebug() << i << " Controller SDL name: " << joytabName; QMenu *joysticksubMenu = nullptr; if (!useSingleList) joysticksubMenu = trayIconMenu->addMenu(joytabName); JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(i)); // static_cast if (widget != nullptr) { QHash *configs = widget->recentConfigs(); QHashIterator configIter(*configs); QList tempProfileList; while (configIter.hasNext()) { configIter.next(); QAction *newaction = nullptr; if (joysticksubMenu != nullptr) { newaction = new QAction(configIter.value(), joysticksubMenu); } else { newaction = new QAction(configIter.value(), trayIconMenu); } newaction->setCheckable(true); newaction->setChecked(false); if (uniques.contains(current->getGUIDString()) && joystickCount < uniques[current->getGUIDString()]) { ++uniques[current->getGUIDString()]; duplicatedGamepad = true; } else if (joystickCount < uniques[current->getGUIDString()]) { uniques.insert(current->getGUIDString(), counterUniques); } int resultDuplicated = 0; if (duplicatedGamepad) resultDuplicated = uniques[current->getGUIDString()]; current->setCounterUniques(resultDuplicated); QString identifier = current->getStringIdentifier(); qDebug() << "current identifier: " << current->getStringIdentifier(); widget->convToUniqueIDControllerGroupSett( m_settings, QString("Controller%1LastSelected").arg(current->getGUIDString()), QString("Controller%1LastSelected").arg(current->getUniqueIDString())); QString controlEntryLastSelected = QString("Controller%1LastSelected").arg(identifier); qDebug() << "controlEntryLastSelected: " << controlEntryLastSelected; duplicatedGamepad = false; QString contrFile = m_settings->value(controlEntryLastSelected).toString(); QFileInfo fileInfo(contrFile); qDebug() << "controlEntryLastSelected in config file: " << contrFile; qDebug() << "fileInfo.exists(): " << fileInfo.exists(); qDebug() << "fileInfo.size(): " << fileInfo.size(); qDebug() << "fileInfo.permissions(): " << fileInfo.permissions(); if ((configIter.value() == fileInfo.baseName()) || (configIter.value() == widget->getCurrentConfigName())) { qDebug() << "fileInfo.baseName(): " << fileInfo.baseName(); qDebug() << "widget->getCurrentConfigName(): " << widget->getCurrentConfigName(); newaction->setChecked(true); } QHash tempmap; qDebug() << "insert " << QString::number(i) << ": " << configIter.key(); tempmap.insert(QString::number(i), QVariant(configIter.key())); QVariant tempvar(tempmap); newaction->setData(tempvar); connect(newaction, &QAction::triggered, this, [this, newaction](bool checked) { profileTrayActionTriggered(newaction, checked); }); if (useSingleList) { qDebug() << "useSingleList"; tempProfileList.append(newaction); } else { qDebug() << "doesn't useSingleList"; joysticksubMenu->addAction(newaction); } } delete configs; configs = nullptr; QAction *newaction = nullptr; if (joysticksubMenu != nullptr) { qDebug() << "joysticksubmenu exists"; newaction = new QAction(tr("Open File"), joysticksubMenu); } else { qDebug() << "created action open file for tray"; newaction = new QAction(tr("Open File"), trayIconMenu); } newaction->setIcon(PadderCommon::loadIcon("document-open", ":/images/actions/document_open.png")); connect(newaction, &QAction::triggered, widget, &JoyTabWidget::openConfigFileDialog); if (useSingleList) { qDebug() << "usesinglelist"; QAction *titleAction = new QAction(joytabName, trayIconMenu); titleAction->setCheckable(false); QFont actionFont = titleAction->font(); actionFont.setBold(true); titleAction->setFont(actionFont); trayIconMenu->addAction(titleAction); trayIconMenu->addActions(tempProfileList); trayIconMenu->addAction(newaction); profileActions.insert(i, tempProfileList); qDebug() << "inserted profile action " << i << ": " << tempProfileList; if (iter.hasNext()) { trayIconMenu->addSeparator(); } } else { joysticksubMenu->addAction(newaction); connect(joysticksubMenu, &QMenu::aboutToShow, this, [this, joysticksubMenu] { joystickTrayShow(joysticksubMenu); }); } i++; } } if (useSingleList) { connect(trayIconMenu, &QMenu::aboutToShow, this, &MainWindow::singleTrayProfileMenuShow); } trayIconMenu->addSeparator(); } trayIconMenu->addAction(hideAction); trayIconMenu->addAction(restoreAction); trayIconMenu->addAction(updateJoy); trayIconMenu->addAction(closeAction); QIcon icon = PadderCommon::loadIcon("antimicrox_trayicon", ":/images/antimicrox.png"); trayIcon->setIcon(icon); trayIcon->setContextMenu(trayIconMenu); qDebug() << "end of MainWindow::populateTrayIcon function"; } void MainWindow::quitProgram() { bool discard = true; #ifdef WITH_X11 AutoProfileWatcher::getAutoProfileWatcherInstance()->disconnectWindowTimer(); #endif for (int i = 0; (i < ui->tabWidget->count()) && discard; i++) { JoyTabWidget *tab = qobject_cast(ui->tabWidget->widget(i)); discard = tab->discardUnsavedProfileChanges(); } if (discard) qApp->quit(); } void MainWindow::refreshTrayIconMenu() { if (this->isHidden()) { hideAction->setEnabled(false); restoreAction->setEnabled(true); } else { hideAction->setEnabled(true); restoreAction->setEnabled(false); } } void MainWindow::trayIconClickAction(QSystemTrayIcon::ActivationReason reason) { if (reason == QSystemTrayIcon::Trigger) { if (this->isHidden()) { this->show(); } else { this->hideWindow(); } } } void MainWindow::mainMenuChange(QMenu *tempMenu) { if (tempMenu == ui->menuQuit) { if (showTrayIcon) { ui->actionHide->setEnabled(true); } else { ui->actionHide->setEnabled(false); } } } void MainWindow::saveAppConfig() { if (m_joysticks->size() > 0) { qInfo() << "Started saving app config"; JoyTabWidget *temptabwidget = qobject_cast(ui->tabWidget->widget(0)); // static_cast m_settings->setValue("DisplayNames", temptabwidget->isDisplayingNames() ? "1" : "0"); m_settings->beginGroup("Controllers"); QStringList tempIdentifierHolder = QStringList(); for (int i = 0; i < ui->tabWidget->count(); i++) { bool prepareSave = true; JoyTabWidget *tabwidget = qobject_cast(ui->tabWidget->widget(i)); // static_cast InputDevice *device = tabwidget->getJoystick(); // Do not allow multi-controller adapters to overwrite each // others recent config file list. Use first controller // detected to save recent config list. Flag controller string // afterwards. if (!device->getStringIdentifier().isEmpty()) { if (tempIdentifierHolder.contains(device->getStringIdentifier())) { prepareSave = false; } else { tempIdentifierHolder.append(device->getStringIdentifier()); } } if (prepareSave) { tabwidget->saveSettings(); } } m_settings->endGroup(); qDebug() << "App config saved"; } m_settings->setValue("WindowSize", size()); m_settings->setValue("WindowPosition", pos()); } void MainWindow::loadAppConfig(bool forceRefresh) { for (int i = 0; i < ui->tabWidget->count(); i++) { JoyTabWidget *tabwidget = qobject_cast(ui->tabWidget->widget(i)); // static_cast tabwidget->loadSettings(forceRefresh); } } void MainWindow::disableFlashActions() { for (int i = 0; i < ui->tabWidget->count(); i++) { QList list = ui->tabWidget->widget(i)->findChildren(); QListIterator iter(list); while (iter.hasNext()) { JoyButtonWidget *buttonWidget = iter.next(); buttonWidget->disableFlashes(); } QList list2 = ui->tabWidget->widget(i)->findChildren(); QListIterator iter2(list2); while (iter2.hasNext()) { JoyAxisWidget *axisWidget = iter2.next(); axisWidget->disableFlashes(); } QList list3 = ui->tabWidget->widget(i)->findChildren(); QListIterator iter3(list3); while (iter3.hasNext()) { JoyControlStickPushButton *stickWidget = iter3.next(); stickWidget->disableFlashes(); } QList list4 = ui->tabWidget->widget(i)->findChildren(); QListIterator iter4(list4); while (iter4.hasNext()) { JoyDPadButtonWidget *dpadWidget = iter4.next(); dpadWidget->disableFlashes(); } QList list6 = ui->tabWidget->widget(i)->findChildren(); QListIterator iter6(list6); while (iter6.hasNext()) { JoyControlStickButtonPushButton *stickButtonWidget = iter6.next(); stickButtonWidget->disableFlashes(); } QList list7 = ui->tabWidget->widget(i)->findChildren(); QListIterator iter7(list7); while (iter7.hasNext()) { DPadPushButton *dpadWidget = iter7.next(); dpadWidget->disableFlashes(); } JoyTabWidget *tabWidget = qobject_cast(ui->tabWidget->widget(i)); // static_cast ui->tabWidget->disableFlashes(tabWidget->getJoystick()); } } void MainWindow::enableFlashActions() { for (int i = 0; i < ui->tabWidget->count(); i++) { QList list = ui->tabWidget->widget(i)->findChildren(); QListIterator iter(list); while (iter.hasNext()) { JoyButtonWidget *buttonWidget = iter.next(); buttonWidget->enableFlashes(); buttonWidget->tryFlash(); } QList list2 = ui->tabWidget->widget(i)->findChildren(); QListIterator iter2(list2); while (iter2.hasNext()) { JoyAxisWidget *axisWidget = iter2.next(); axisWidget->enableFlashes(); axisWidget->tryFlash(); } QList list3 = ui->tabWidget->widget(i)->findChildren(); QListIterator iter3(list3); while (iter3.hasNext()) { JoyControlStickPushButton *stickWidget = iter3.next(); stickWidget->enableFlashes(); stickWidget->tryFlash(); } QList sensors = ui->tabWidget->widget(i)->findChildren(); for (const auto &sensorWidget : sensors) { sensorWidget->enableFlashes(); sensorWidget->tryFlash(); } QList list4 = ui->tabWidget->widget(i)->findChildren(); QListIterator iter4(list4); while (iter4.hasNext()) { JoyDPadButtonWidget *dpadWidget = iter4.next(); dpadWidget->enableFlashes(); dpadWidget->tryFlash(); } QList list6 = ui->tabWidget->widget(i)->findChildren(); QListIterator iter6(list6); while (iter6.hasNext()) { JoyControlStickButtonPushButton *stickButtonWidget = iter6.next(); stickButtonWidget->enableFlashes(); stickButtonWidget->tryFlash(); } QList list7 = ui->tabWidget->widget(i)->findChildren(); QListIterator iter7(list7); while (iter7.hasNext()) { DPadPushButton *dpadWidget = iter7.next(); dpadWidget->enableFlashes(); dpadWidget->tryFlash(); } JoyTabWidget *tabWidget = qobject_cast(ui->tabWidget->widget(i)); // static_cast ui->tabWidget->enableFlashes(tabWidget->getJoystick()); } } // Intermediate slot used in Design mode void MainWindow::hideWindow() { disableFlashActions(); signalDisconnect = true; hide(); } void MainWindow::joystickTrayShow(QMenu *tempmenu) { QList menuactions = tempmenu->actions(); QListIterator listiter(menuactions); while (listiter.hasNext()) { QAction *action = listiter.next(); action->setChecked(false); QHash tempmap = action->data().toHash(); QHashIterator iter(tempmap); while (iter.hasNext()) { iter.next(); int joyindex = iter.key().toInt(); int configindex = iter.value().toInt(); JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(joyindex)); // static_cast if (configindex == widget->getCurrentConfigIndex()) { action->setChecked(true); if (widget->getJoystick()->isDeviceEdited()) { action->setIcon(PadderCommon::loadIcon("document-save-as", ":/images/actions/document_save_as.png")); } else if (!action->icon().isNull()) { action->setIcon(QIcon()); } } else if (!action->icon().isNull()) { action->setIcon(QIcon()); } if (action->text() != widget->getConfigName(configindex)) { action->setText(widget->getConfigName(configindex)); } } } } void MainWindow::showEvent(QShowEvent *event) { // Check if hideEvent has been processed if (signalDisconnect && isVisible()) { // Restore flashing buttons enableFlashActions(); signalDisconnect = false; // Only needed if hidden with the system tray enabled if (showTrayIcon) { if (isMinimized()) { if (isMaximized()) { showMaximized(); } else { showNormal(); } activateWindow(); raise(); } } } QMainWindow::showEvent(event); } void MainWindow::changeEvent(QEvent *event) { if (event->type() == QEvent::WindowStateChange) { QWindowStateChangeEvent *e = static_cast(event); if (e->oldState() != Qt::WindowMinimized && isMinimized()) { bool minimizeToTaskbar = m_settings->value("MinimizeToTaskbar", false).toBool(); if (QSystemTrayIcon::isSystemTrayAvailable() && showTrayIcon && !minimizeToTaskbar) { this->hideWindow(); } else { disableFlashActions(); signalDisconnect = true; } } } else if (event->type() == QEvent::LanguageChange) { retranslateUi(); } QMainWindow::changeEvent(event); } void MainWindow::openAboutDialog() { aboutDialog->show(); } void MainWindow::loadConfigFile(QString fileLocation, int joystickIndex) { if ((joystickIndex > 0) && m_joysticks->contains(joystickIndex - 1)) { JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(joystickIndex - 1)); // static_cast if (widget != nullptr) { widget->loadConfigFile(fileLocation); } } else if (joystickIndex <= 0) { for (int i = 0; i < ui->tabWidget->count(); i++) { JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(i)); // static_cast if (widget != nullptr) { widget->loadConfigFile(fileLocation); } } } } void MainWindow::loadConfigFile(QString fileLocation, QString controllerID) { if (!controllerID.isEmpty()) { QListIterator iter(ui->tabWidget->findChildren()); while (iter.hasNext()) { JoyTabWidget *tab = iter.next(); if (tab != nullptr) { InputDevice *tempdevice = tab->getJoystick(); if (controllerID == tempdevice->getStringIdentifier()) { tab->loadConfigFile(fileLocation); } } } } } void MainWindow::removeJoyTabs() { int oldtabcount = ui->tabWidget->count(); for (int i = oldtabcount - 1; i >= 0; i--) { QWidget *tab = ui->tabWidget->widget(i); delete tab; tab = nullptr; } ui->tabWidget->clear(); } void MainWindow::handleInstanceDisconnect() { m_settings->sync(); loadAppConfig(true); } void MainWindow::openJoystickStatusWindow() { int index = ui->tabWidget->currentIndex(); if (index >= 0) { JoyTabWidget *joyTab = qobject_cast(ui->tabWidget->widget(index)); // static_cast InputDevice *joystick = joyTab->getJoystick(); if (joystick != nullptr) { JoystickStatusWindow *dialog = new JoystickStatusWindow(joystick, this); dialog->show(); } } } void MainWindow::openKeyCheckerDialog() { QKeyDisplayDialog *dialog = new QKeyDisplayDialog(this); dialog->show(); } void MainWindow::openGitHubPage() { QDesktopServices::openUrl(QUrl(PadderCommon::githubProjectPage)); } void MainWindow::openIssuesPage() { QDesktopServices::openUrl(QUrl(PadderCommon::githubIssuesPage)); } void MainWindow::openWikiPage() { QDesktopServices::openUrl(QUrl(PadderCommon::wikiPage)); } void MainWindow::openCalibration() { if (m_joysticks->isEmpty()) { QMessageBox::information(this, tr("Calibration couldn't be opened"), tr("You must connect at least one controller to open the window")); } else { int index = ui->tabWidget->currentIndex(); if (index >= 0) { JoyTabWidget *joyTab = qobject_cast(ui->tabWidget->widget(index)); // static_cast InputDevice *device = joyTab->getJoystick(); if (device != nullptr) { QPointer calibration = new Calibration(device); calibration.data()->show(); if (calibration.isNull()) calibration.clear(); } } } } void MainWindow::unloadCurrentConfig(int joystickIndex) { if ((joystickIndex > 0) && m_joysticks->contains(joystickIndex - 1)) { JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(joystickIndex - 1)); // static_cast if (widget != nullptr) { widget->unloadConfig(); } } else if (joystickIndex <= 0) { for (int i = 0; i < ui->tabWidget->count(); i++) { JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(i)); // static_cast if (widget != nullptr) { widget->unloadConfig(); } } } } void MainWindow::unloadCurrentConfig(QString controllerID) { if (!controllerID.isEmpty()) { QListIterator iter(ui->tabWidget->findChildren()); while (iter.hasNext()) { JoyTabWidget *tab = iter.next(); if (tab != nullptr) { InputDevice *tempdevice = tab->getJoystick(); if (controllerID == tempdevice->getStringIdentifier()) { tab->unloadConfig(); } } } } } void MainWindow::propogateNameDisplayStatus(JoyTabWidget *tabwidget, bool displayNames) { for (int i = 0; i < ui->tabWidget->count(); i++) { JoyTabWidget *tab = qobject_cast(ui->tabWidget->widget(i)); // static_cast if ((tab != nullptr) && (tab != tabwidget)) { if (tab->isDisplayingNames() != displayNames) { tab->changeNameDisplay(displayNames); } } } } void MainWindow::changeStartSetNumber(int startSetNumber, QString controllerID) { if (!controllerID.isEmpty()) { QListIterator iter(ui->tabWidget->findChildren()); while (iter.hasNext()) { JoyTabWidget *tab = iter.next(); if (tab != nullptr) { InputDevice *tempdevice = tab->getJoystick(); if (controllerID == tempdevice->getStringIdentifier()) { tab->changeCurrentSet(startSetNumber); } } } } } void MainWindow::changeStartSetNumber(int startSetNumber, int joystickIndex) { if ((joystickIndex > 0) && m_joysticks->contains(joystickIndex - 1)) { JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(joystickIndex - 1)); // static_cast if (widget != nullptr) { widget->changeCurrentSet(startSetNumber); } } else if (joystickIndex <= 0) { for (int i = 0; i < ui->tabWidget->count(); i++) { JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(i)); // static_cast if (widget != nullptr) { widget->changeCurrentSet(startSetNumber); } } } } /** * @brief Build list of current input devices and pass it to settings dialog * instance. Open Settings dialog. */ void MainWindow::openMainSettingsDialog() { QList *devices = new QList(m_joysticks->values()); MainSettingsDialog *dialog = new MainSettingsDialog(m_settings, devices, this); connect(dialog, &MainSettingsDialog::changeLanguage, this, &MainWindow::changeLanguage); if (appWatcher != nullptr) { #if defined(WITH_X11) if (QApplication::platformName() == QStringLiteral("xcb")) { connect(dialog, &MainSettingsDialog::accepted, appWatcher, &AutoProfileWatcher::syncProfileAssignment); connect(dialog, &MainSettingsDialog::accepted, this, &MainWindow::checkAutoProfileWatcherTimer); connect(dialog, &MainSettingsDialog::rejected, this, &MainWindow::checkAutoProfileWatcherTimer); appWatcher->stopTimer(); qDebug() << "Stopping appWatcher in openMainSettingsDialog"; } #elif defined(Q_OS_WIN) connect(dialog, &MainSettingsDialog::accepted, appWatcher, &AutoProfileWatcher::syncProfileAssignment); connect(dialog, &MainSettingsDialog::accepted, this, &MainWindow::checkAutoProfileWatcherTimer); connect(dialog, &MainSettingsDialog::rejected, this, &MainWindow::checkAutoProfileWatcherTimer); appWatcher->stopTimer(); #endif } connect(dialog, &MainSettingsDialog::accepted, this, &MainWindow::populateTrayIcon); connect(dialog, &MainSettingsDialog::accepted, this, &MainWindow::checkHideEmptyOption); dialog->show(); } /** * @brief Change language used by the application. * @param Language code */ void MainWindow::changeLanguage(QString language) { if ((m_translator != nullptr) && (m_appTranslator != nullptr)) { PadderCommon::reloadTranslations(m_translator, m_appTranslator, language); } } /** * @brief Check if the program should really quit or if it should * be minimized. * @param QCloseEvent */ void MainWindow::closeEvent(QCloseEvent *event) { bool closeToTray = m_settings->value("CloseToTray", false).toBool(); if (closeToTray && QSystemTrayIcon::isSystemTrayAvailable() && showTrayIcon) { this->hideWindow(); } else { qApp->quit(); } QMainWindow::closeEvent(event); } /** * @brief Show abstracted controller dialog for use in SDL 1.2. No longer * used for versions of the program running SDL 2. In SDL 2, * the Game Controller API is being used instead. */ void MainWindow::showStickAssignmentDialog() { int index = ui->tabWidget->currentIndex(); if (index >= 0) { JoyTabWidget *joyTab = qobject_cast(ui->tabWidget->widget(index)); // static_cast Joystick *joystick = qobject_cast(joyTab->getJoystick()); // static_cast AdvanceStickAssignmentDialog *dialog = new AdvanceStickAssignmentDialog(joystick, this); connect(dialog, &AdvanceStickAssignmentDialog::finished, joyTab, &JoyTabWidget::fillButtons); dialog->show(); } } /** * @brief Display a version of the tray menu that shows all recent profiles for * all controllers in one list. */ void MainWindow::singleTrayProfileMenuShow() { if (!getProfileActions().isEmpty()) { QMapIterator> mapIter(getProfileActions()); while (mapIter.hasNext()) { mapIter.next(); QList menuactions = mapIter.value(); QListIterator listiter(menuactions); while (listiter.hasNext()) { QAction *action = listiter.next(); action->setChecked(false); QHash tempmap = action->data().toHash(); QHashIterator iter(tempmap); while (iter.hasNext()) { iter.next(); int joyindex = iter.key().toInt(); int configindex = iter.value().toInt(); JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(joyindex)); // static_cast if (configindex == widget->getCurrentConfigIndex()) { action->setChecked(true); if (widget->getJoystick()->isDeviceEdited()) { action->setIcon( PadderCommon::loadIcon("document-save-as", ":/images/actions/document_save_as.png")); } else if (!action->icon().isNull()) { action->setIcon(QIcon()); } } else if (!action->icon().isNull()) { action->setIcon(QIcon()); } if (action->text() != widget->getConfigName(configindex)) { action->setText(widget->getConfigName(configindex)); } } } } } } void MainWindow::profileTrayActionTriggered(QAction *action, bool checked) { // Obtaining the selected config QHash tempmap = action->data().toHash(); QHashIterator iter(tempmap); while (iter.hasNext()) { iter.next(); // Fetching indicies and tab associated with the current joypad int joyindex = iter.key().toInt(); int configindex = iter.value().toInt(); JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(joyindex)); // static_cast // Checking if the selected config has been disabled by the change (action->isChecked() represents the state of the // checkbox AFTER the click) if (!checked) { // It has - disabling - the 0th config is the new/'null' config widget->setCurrentConfig(0); } else { // It hasn't - enabling - note that setting this causes the menu to be updated widget->setCurrentConfig(configindex); } } } void MainWindow::checkHideEmptyOption() { for (int i = 0; i < ui->tabWidget->count(); i++) { JoyTabWidget *tab = qobject_cast(ui->tabWidget->widget(i)); // static_cast if (tab != nullptr) { tab->checkHideEmptyOption(); } } } #ifdef Q_OS_WIN /** * @brief Check if user really wants to restart the program with elevated * privileges. If yes, attempt to restart the program. */ void MainWindow::restartAsElevated() { QMessageBox msg; msg.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msg.setWindowTitle(tr("Run as Administrator?")); msg.setText(tr("Are you sure that you want to run this program as Adminstrator?" "\n\n" "Some games run as Administrator which will cause events generated by antimicro " "to not be used by those games unless antimicro is also run " "as the Adminstrator. " "This is due to permission problems caused by User Account " "Control (UAC) options in Windows Vista and later.")); QIcon uacIcon = QApplication::style()->standardIcon(QStyle::SP_VistaShield); msg.button(QMessageBox::Yes)->setIcon(uacIcon); int result = msg.exec(); if (result == QMessageBox::Yes) { bool result = WinExtras::elevateAntiMicro(); if (result) { qApp->quit(); } else { msg.setStandardButtons(QMessageBox::Close); msg.setWindowTitle(tr("Failed to elevate program")); msg.setText(tr("Failed to restart this program as the Administrator")); msg.exec(); } } } #endif void MainWindow::propogateMappingUpdate(QString mapping, InputDevice *device) { emit mappingUpdated(mapping, device); } void MainWindow::testMappingUpdateNow(int index, InputDevice *device) { QWidget *tab = ui->tabWidget->widget(index); if (tab != nullptr) { ui->tabWidget->removeTab(index); delete tab; tab = nullptr; } JoyTabWidget *tabwidget = new JoyTabWidget(device, m_settings, this); QString joytabName = device->getSDLName(); joytabName.append(" ").append(tr("(%1)").arg(device->getName())); ui->tabWidget->insertTab(index, tabwidget, joytabName); tabwidget->refreshButtons(); ui->tabWidget->setCurrentIndex(index); connect(tabwidget, &JoyTabWidget::namesDisplayChanged, this, [this, tabwidget](bool displayNames) { propogateNameDisplayStatus(tabwidget, displayNames); }); connect(tabwidget, &JoyTabWidget::mappingUpdated, this, &MainWindow::propogateMappingUpdate); if (showTrayIcon) { connect(tabwidget, &JoyTabWidget::joystickConfigChanged, this, &MainWindow::populateTrayIcon); populateTrayIcon(); } } void MainWindow::removeJoyTab(SDL_JoystickID deviceID) { bool found = false; for (int i = 0; (i < ui->tabWidget->count()) && !found; i++) { JoyTabWidget *tab = qobject_cast(ui->tabWidget->widget(i)); // static_cast if ((tab != nullptr) && (deviceID == tab->getJoystick()->getSDLJoystickID())) { // Save most recent profile list to settings before removing tab. tab->saveDeviceSettings(); // Remove flash event connections between buttons and // the tab before deleting tab. ui->tabWidget->disableFlashes(tab->getJoystick()); ui->tabWidget->removeTab(i); QMetaObject::invokeMethod(tab->getJoystick(), "finalRemoval"); delete tab; tab = nullptr; found = true; } } // Refresh tab text to reflect new index values. for (int i = 0; i < ui->tabWidget->count(); i++) { JoyTabWidget *tab = qobject_cast(ui->tabWidget->widget(i)); // static_cast if (tab != nullptr) { InputDevice *device = tab->getJoystick(); QString joytabName = device->getSDLName(); joytabName.append(" ").append(tr("(%1)").arg(device->getName())); ui->tabWidget->setTabText(i, joytabName); } } if (showTrayIcon) populateTrayIcon(); if (ui->tabWidget->count() == 0) { ui->stackedWidget->setCurrentIndex(0); } } void MainWindow::addJoyTab(InputDevice *device) { JoyTabWidget *tabwidget = new JoyTabWidget(device, m_settings, this); QString joytabName = device->getSDLName(); joytabName.append(" ").append(tr("(%1)").arg(device->getName())); ui->tabWidget->addTab(tabwidget, joytabName); tabwidget->loadDeviceSettings(); tabwidget->refreshButtons(); // Refresh tab text to reflect new index values. for (int i = 0; i < ui->tabWidget->count(); i++) { JoyTabWidget *tab = qobject_cast(ui->tabWidget->widget(i)); // static_cast if (tab != nullptr) { InputDevice *device_in_loop = tab->getJoystick(); QString joytabName_in_loop = device_in_loop->getSDLName(); joytabName_in_loop.append(" ").append(tr("(%1)").arg(device_in_loop->getName())); ui->tabWidget->setTabText(i, joytabName_in_loop); } } connect(tabwidget, &JoyTabWidget::namesDisplayChanged, this, [this, tabwidget](bool displayNames) { propogateNameDisplayStatus(tabwidget, displayNames); }); connect(tabwidget, &JoyTabWidget::mappingUpdated, this, &MainWindow::propogateMappingUpdate); if (showTrayIcon) { connect(tabwidget, &JoyTabWidget::joystickConfigChanged, this, &MainWindow::populateTrayIcon); populateTrayIcon(); } ui->stackedWidget->setCurrentIndex(1); } void MainWindow::autoprofileLoad(AutoProfileInfo *info) { if (info != nullptr) { qDebug() << QString("Auto-switching to profile \"%1\".").arg(info->getProfileLocation()); } else { qCritical() << QString("Auto-switching to nullptr profile!"); } #if defined(WITH_X11) || defined(Q_OS_WIN) #if defined(WITH_X11) if (QApplication::platformName() != QStringLiteral("xcb")) return; #endif for (int i = 0; i < ui->tabWidget->count(); i++) { JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(i)); // static_cast if (widget != nullptr) { // if (info->getGUID() == "all") if (info->getUniqueID() == "all") { // If the all option for a Default profile was found, // first check for controller specific associations. If one exists, // skip changing the profile on the controller. A later call will // be used to switch the profile for that controller. QList *customs = appWatcher->getCustomDefaults(); bool found = false; QListIterator iter(*customs); while (iter.hasNext()) { AutoProfileInfo *tempinfo = iter.next(); // if (tempinfo->getGUID() == widget->getJoystick()->getGUIDString() && if (tempinfo->getUniqueID() == widget->getJoystick()->getUniqueIDString() && info->isCurrentDefault()) { found = true; iter.toBack(); qDebug() << "autoProfileInfo has the same GUID as GUID of joystick and the autoProfile is " "default. Found = true."; } } delete customs; customs = nullptr; // Check if profile has already been switched for a particular // controller. if (!found) { // QString tempguid = widget->getJoystick()->getGUIDString(); // if (appWatcher->isGUIDLocked(tempguid)) QString tempguid = widget->getJoystick()->getUniqueIDString(); if (appWatcher->isUniqueIDLocked(tempguid)) { found = true; qDebug() << "GUID is locked in appWatcher. Found = true."; } } if (!found) { // If the profile location is empty, assume // that an empty profile should get loaded. if (info->getProfileLocation().isEmpty()) { widget->setCurrentConfig(0); qDebug() << "profile location is empty. setCurrentConfig(0)"; } else { widget->loadConfigFile(info->getProfileLocation()); qDebug() << "loaded config file for current AutoLoadInfo"; } } } // else if (info->getGUID() == widget->getJoystick()->getStringIdentifier()) else if (info->getUniqueID() == widget->getJoystick()->getStringIdentifier()) { // qDebug() << "GUID of AutoProfileInfo: " << info->getGUID() << " == string identifier of // AutoProfileInfo: " << widget->getJoystick()->getStringIdentifier(); qDebug() << "GUID of AutoProfileInfo: " << info->getUniqueID() << " == string identifier of AutoProfileInfo: " << widget->getJoystick()->getStringIdentifier(); if (info->getProfileLocation().isEmpty()) { qDebug() << "profile location of AutoProfileInfo is empty. Set first config"; widget->setCurrentConfig(0); } else { qDebug() << "load config file for AutoProfileInfo"; widget->loadConfigFile(info->getProfileLocation()); } } } } #endif } void MainWindow::checkAutoProfileWatcherTimer() { #if defined(WITH_X11) || defined(Q_OS_WIN) #if defined(WITH_X11) if (QApplication::platformName() != QStringLiteral("xcb")) return; #endif QString autoProfileActive = m_settings->value("AutoProfiles/AutoProfilesActive", "0").toString(); if (autoProfileActive == "1") { appWatcher->startTimer(); qDebug() << "Started timer for appWatcher"; } else { appWatcher->stopTimer(); qDebug() << "Stopped timer for appWatcher"; } #endif } /** * @brief TODO: Check if method is save to remove. */ void MainWindow::updateMenuOptions() { int index = ui->tabWidget->currentIndex(); if (index >= 0) { JoyTabWidget *joyTab = qobject_cast(ui->tabWidget->widget(index)); // static_cast InputDevice *joystick = joyTab->getJoystick(); if (qobject_cast(joystick) != nullptr) { ui->actionStick_Pad_Assign->setEnabled(false); } else { ui->actionStick_Pad_Assign->setEnabled(true); } } } void MainWindow::showBatteryLevel(SDL_JoystickPowerLevel powerLevSDL, QString batteryLev, QString percent, InputDevice *device) { if (SDL_JoystickCurrentPowerLevel(device->getJoyHandle()) == powerLevSDL) { QResource batteryFile(":/images/battery-low-level.png"); QPixmap pm(30, 30); pm.load(batteryFile.absoluteFilePath()); QMessageBox msgBox; msgBox.setWindowTitle(tr("%1 battery").arg(batteryLev)); msgBox.setIconPixmap(pm); msgBox.setText(tr("Battery level is less than %1").arg(percent)); msgBox.setInformativeText( tr("Device number: %1\nDevice name: %2").arg(device->getRealJoyNumber()).arg(device->getSDLName())); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); msgBox.exec(); } } #ifdef CHECK_FOR_UPDATES void MainWindow::networkManagerFinished(QNetworkReply *reply) { int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (status_code != 200) { WARN() << "Invalid REST response status code: " << status_code; VERBOSE() << "Supports SSL: " << (QSslSocket::supportsSsl() ? "true " : "false ") << QSslSocket::sslLibraryBuildVersionString() << QSslSocket::sslLibraryVersionString(); return; } QJsonDocument json = QJsonDocument::fromJson(reply->readAll()); QJsonObject doc = json.object(); QString latest_version = doc["tag_name"].toString().split("-")[0]; // remove notes from versions like 3.2.1-debug DEBUG() << "Latest version: " << latest_version << " Installed version: " << PadderCommon::programVersion; if (latest_version != PadderCommon::programVersion && latest_version.length()) { INFO() << "Update to: " << latest_version << " is available."; ui->updateButton->setVisible(true); ui->updateButton->setText(tr("Update to %1 available").arg(latest_version)); connect(ui->updateButton, &QPushButton::clicked, this, &MainWindow::updateButtonPressed); } } void MainWindow::updateButtonPressed() { INFO() << "Opening update website"; QDesktopServices::openUrl(QUrl("https://github.com/antiMicroX/antimicrox/releases/latest")); } #endif /** * @brief Select appropriate tab that has a device with the specified GUID. * @param GUID of joystick device. */ void MainWindow::selectControllerJoyTab(QString GUID) { if (!GUID.isEmpty()) { InputDevice *device = nullptr; QMapIterator deviceIter(*m_joysticks); while (deviceIter.hasNext()) { deviceIter.next(); InputDevice *tempDevice = deviceIter.value(); if (tempDevice && (GUID == tempDevice->getStringIdentifier())) { device = tempDevice; deviceIter.toBack(); } } if (device != nullptr) { qDebug() << "InputDevice was not a null pointer in selectControllerJoyTab of GUID"; ui->tabWidget->setCurrentIndex(device->getJoyNumber()); } else { qDebug() << "InputDevice was a NULL POINTER in selectControllerJoyTab of GUID"; } } } void MainWindow::changeWindowStatus() { // Check flags to see if user requested for the main window and the tray icon // to not be displayed. if (m_graphical) { bool launchInTraySetting = m_settings->runtimeValue("LaunchInTray", false).toBool(); if (!m_cmdutility->isHiddenRequested() && (!launchInTraySetting || !QSystemTrayIcon::isSystemTrayAvailable())) { show(); } else if (m_cmdutility->isHiddenRequested() && m_cmdutility->isTrayHidden()) { // Window should already be hidden but make sure // to disable flashing buttons. hideWindow(); setEnabled(false); // Should already be disabled. Do it again just to be sure. } else if (m_cmdutility->isHiddenRequested() || launchInTraySetting) { // Window should already be hidden but make sure // to disable flashing buttons. hideWindow(); setEnabled(true); } } } bool MainWindow::getGraphicalStatus() { return m_graphical; } void MainWindow::setTranslator(QTranslator *translator) { m_translator = translator; } QTranslator *MainWindow::getTranslator() const { return m_translator; } void MainWindow::setAppTranslator(QTranslator *translator) { m_appTranslator = translator; } QTranslator *MainWindow::getAppTranslator() const { return m_appTranslator; } void MainWindow::retranslateUi() { ui->retranslateUi(this); } void MainWindow::refreshTabHelperThreads() { for (int i = 0; i < ui->tabWidget->count(); i++) { JoyTabWidget *widget = qobject_cast(ui->tabWidget->widget(i)); if (widget != nullptr) { widget->refreshHelperThread(); } } } QMap> const &MainWindow::getProfileActions() { return profileActions; } bool MainWindow::isKeypadUnlocked() { if (m_settings == nullptr) return false; return m_settings->value("AttachNumKeypad", false).toBool(); } bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::Hide && (obj != nullptr)) { obj->deleteLater(); } return false; } void MainWindow::convertGUIDtoUniqueID(InputDevice *currentDevice, QString controlEntryLastSelectedGUID) { int exec = QMessageBox::information( this, tr("Reading old profile"), tr("This profile uses controllers' GUID numbers. Would you like to change GUID numbers to UniqueID in this file for " "use in identical gamecontrollers? Such old file cannot be loaded in antimicrox since version 2.25"), QMessageBox::Yes, QMessageBox::No); switch (exec) { case QMessageBox::Yes: QFile data(m_settings->value(controlEntryLastSelectedGUID).toString()); data.open(QIODevice::Text | QIODevice::ReadOnly); QString dataText = data.readAll(); QRegularExpression re(currentDevice->getGUIDString()); QString replacementText(currentDevice->getUniqueIDString()); dataText.replace(re, replacementText); QFile newData(m_settings->value(controlEntryLastSelectedGUID).toString()); if (newData.open(QFile::WriteOnly | QFile::Truncate)) { QTextStream out(&newData); out << dataText; } else WARN() << "Could not open file: " << newData.fileName(); newData.close(); break; } } void MainWindow::checkEachTenMinutesBattery(QMap *joysticks) { QMapIterator deviceIter(*joysticks); bool notify_about_empty_battery = m_settings->value("Notifications/notify_about_empty_battery", true).toBool(); bool notify_about_low_battery = m_settings->value("Notifications/notify_about_low_battery", true).toBool(); while (deviceIter.hasNext()) { deviceIter.next(); InputDevice *tempDevice = deviceIter.value(); if (notify_about_low_battery) showBatteryLevel(SDL_JOYSTICK_POWER_LOW, "Low", "20%", tempDevice); if (notify_about_empty_battery) showBatteryLevel(SDL_JOYSTICK_POWER_EMPTY, "Empty", "5%", tempDevice); } } AntiMicroX-antimicrox-b300273/src/gui/mainwindow.h000066400000000000000000000141261471077622000220560ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include #include #ifdef CHECK_FOR_UPDATES #include #include #endif class InputDevice; class CommandLineUtility; class AntiMicroSettings; class QWidget; class QTranslator; class AutoProfileInfo; class AutoProfileWatcher; class QLocalServer; class AboutDialog; class QAction; class QMenu; class QShowEvent; class QEvent; class QCloseEvent; class JoyTabWidget; namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QMap *joysticks, CommandLineUtility *cmdutility, AntiMicroSettings *settings, bool graphical = true, QWidget *parent = nullptr); ~MainWindow(); bool getGraphicalStatus(); void setTranslator(QTranslator *translator); QTranslator *getTranslator() const; void setAppTranslator(QTranslator *translator); QTranslator *getAppTranslator() const; QMap> const &getProfileActions(); bool isKeypadUnlocked(); protected: virtual void showEvent(QShowEvent *event); virtual void changeEvent(QEvent *event); virtual void closeEvent(QCloseEvent *event); bool eventFilter(QObject *obj, QEvent *event) override; void retranslateUi(); void loadConfigFile(QString fileLocation, int joystickIndex = 0); // MainConfiguration class void loadConfigFile(QString fileLocation, QString controllerID); // MainConfiguration class void unloadCurrentConfig(int joystickIndex = 0); // MainConfiguration class void unloadCurrentConfig(QString controllerID); // MainConfiguration class void changeStartSetNumber(int startSetNumber, QString controllerID); // MainConfiguration class void changeStartSetNumber(int startSetNumber, int joystickIndex = 0); // MainConfiguration class void convertGUIDtoUniqueID(InputDevice *currentDevice, QString controlEntryLastSelectedGUID); signals: void joystickRefreshRequested(); void readConfig(int index); // MainConfiguration class void mappingUpdated(QString mapping, InputDevice *device); public slots: void checkEachTenMinutesBattery(QMap *joysticks); void fillButtons(); void makeJoystickTabs(); void alterConfigFromSettings(); // MainConfiguration class void fillButtonsID(InputDevice *joystick); void fillButtonsMap(QMap *joysticks); void startJoystickRefresh(); void hideWindow(); void saveAppConfig(); // MainConfiguration class void loadAppConfig(bool forceRefresh = false); // MainConfiguration class void removeJoyTabs(); void quitProgram(); void changeWindowStatus(); void refreshTabHelperThreads(); void testMappingUpdateNow(int index, InputDevice *device); void removeJoyTab(SDL_JoystickID deviceID); void addJoyTab(InputDevice *device); void selectControllerJoyTab(QString GUID); void handleInstanceDisconnect(); private slots: void refreshTrayIconMenu(); void trayIconClickAction(QSystemTrayIcon::ActivationReason reason); void mainMenuChange(QMenu *tempMenu); void disableFlashActions(); void enableFlashActions(); void joystickTrayShow(QMenu *tempmenu); void singleTrayProfileMenuShow(); void profileTrayActionTriggered(QAction *action, bool checked); void populateTrayIcon(); void openAboutDialog(); void openJoystickStatusWindow(); void openKeyCheckerDialog(); void openGitHubPage(); void openIssuesPage(); void openWikiPage(); void openCalibration(); void propogateNameDisplayStatus(JoyTabWidget *tabwidget, bool displayNames); void changeLanguage(QString language); // MainConfiguration class void openMainSettingsDialog(); void showStickAssignmentDialog(); void checkHideEmptyOption(); #ifdef Q_OS_WIN void restartAsElevated(); #endif void propogateMappingUpdate(QString mapping, InputDevice *device); void autoprofileLoad(AutoProfileInfo *info); // MainConfiguration class void checkAutoProfileWatcherTimer(); // MainConfiguration class void updateMenuOptions(); private: /** * @brief Check state of batteries in controllers and notify user (only when powerLevSDL matches current battery level) */ void showBatteryLevel(SDL_JoystickPowerLevel powerLevSDL, QString batteryLev, QString percent, InputDevice *device); Ui::MainWindow *ui; QMap *m_joysticks; QMap> profileActions; QSystemTrayIcon *trayIcon; QMenu *trayIconMenu; AboutDialog *aboutDialog; CommandLineUtility *m_cmdutility; AntiMicroSettings *m_settings; QTranslator *m_translator; QTranslator *m_appTranslator; AutoProfileWatcher *appWatcher; QAction *hideAction; QAction *restoreAction; QAction *closeAction; QAction *updateJoy; bool signalDisconnect; bool showTrayIcon; bool m_graphical; #ifdef CHECK_FOR_UPDATES QNetworkAccessManager m_network_manager; // Used for checking updates void networkManagerFinished(QNetworkReply *reply); void updateButtonPressed(); #endif }; #endif // MAINWINDOW_H AntiMicroX-antimicrox-b300273/src/gui/mainwindow.ui000066400000000000000000000364071471077622000222520ustar00rootroot00000000000000 MainWindow Qt::WindowModal 0 0 650 580 650 0 AntiMicroX .. FlashButtonWidget[isflashing="true"] { background-color: rgb(0, 0, 255); color: rgb(205, 197, 191); } QPushButton#setPushButton1[setActive="false"], QPushButton#setPushButton2[setActive="false"], QPushButton#setPushButton3[setActive="false"], QPushButton#setPushButton4[setActive="false"], QPushButton#setPushButton5[setActive="false"], QPushButton#setPushButton6[setActive="false"], QPushButton#setPushButton7[setActive="false"], QPushButton#setPushButton8[setActive="false"] { background-color: rgb(190, 190, 190); } QStackedWidget#stackedWidget{ padding-top: 10px; } QPushButton#namesPushButton[isDisplayingNames="true"] { background-color: rgb(192, 255, 192); } 4 0 0 0 0 QFrame::NoFrame QFrame::Plain 1 1 No Joysticks have been found. Please plug in a joystick and then choose the "Update Joysticks" option in the main menu true Qt::AlignCenter true 0 0 0 0 0 0 true 0 0 Qt::LeftToRight QTabWidget::North QTabWidget::Rounded -1 true false false false 1 0 If events are not seen by a game, please click here to run this application as Administrator. false false false 1 0 Update Button false false false 0 0 650 22 &App &Options He&lp :/images/actions/application_exit.png:/images/actions/application_exit.png &Quit Ctrl+Q true :/images/actions/view_refresh.png:/images/actions/view_refresh.png &Update Joysticks Ctrl+U :/images/actions/view_restore.png:/images/actions/view_restore.png &Hide Ctrl+H :/images/actions/about_antimicrox.png:/images/actions/about_antimicrox.png &About Ctrl+A :/images/actions/about_qt.png:/images/actions/about_qt.png About &Qt Ctrl+T :/images/actions/sliders.png:/images/actions/sliders.png &Properties Ctrl+P :/images/actions/key_checker.png:/images/actions/key_checker.png &Key Checker Ctrl+K Home Page Ctrl+H :/images/actions/github_page.png:/images/actions/github_page.png &GitHub Page Ctrl+G :/images/actions/settings.png:/images/actions/settings.png S&ettings Ctrl+S :/images/actions/stick_pad_assign.png:/images/actions/stick_pad_assign.png &Stick/Pad Assign Ctrl+X :/images/actions/wiki.png:/images/actions/wiki.png &Wiki Ctrl+W :/images/actions/issues.png:/images/actions/issues.png &Issues Ctrl+I :/images/actions/calibration.png:/images/actions/calibration.png &Calibration Ctrl+C JoyTabWidgetContainer QTabWidget
joytabwidgetcontainer.h
1
actionQuit triggered() MainWindow quitProgram() -1 -1 199 149 actionUpdate_Joysticks triggered() MainWindow startJoystickRefresh() -1 -1 349 262 actionHide triggered() MainWindow hideWindow() -1 -1 349 262 actionAbout triggered() MainWindow openAboutDialog() -1 -1 349 262 actionStick_Pad_Assign triggered() MainWindow showStickAssignmentDialog() -1 -1 324 289 startJoystickRefresh() hideWindow() openAboutDialog() quitProgram() showStickAssignmentDialog()
AntiMicroX-antimicrox-b300273/src/gui/mousesettingsdialog.cpp000066400000000000000000000325051471077622000243270ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mousesettingsdialog.h" #include "ui_mousesettingsdialog.h" #include "globalvariables.h" #include #include #include #include #include #include #include MouseSettingsDialog::MouseSettingsDialog(QWidget *parent) : QDialog(parent, Qt::Window) , ui(new Ui::MouseSettingsDialog) { ui->setupUi(this); ui->horizontalSpinBox->setMaximum(GlobalVariables::JoyButton::MAXMOUSESPEED); ui->verticalSpinBox->setMaximum(GlobalVariables::JoyButton::MAXMOUSESPEED); setAttribute(Qt::WA_DeleteOnClose); JoyButtonMouseHelper *mouseHelper = JoyButton::getMouseHelper(); connect(mouseHelper, &JoyButtonMouseHelper::mouseCursorMoved, this, &MouseSettingsDialog::updateMouseCursorStatusLabels); connect(mouseHelper, &JoyButtonMouseHelper::mouseSpringMoved, this, &MouseSettingsDialog::updateMouseSpringStatusLabels); lastMouseStatUpdate.start(); connect(ui->accelerationComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseSettingsDialog::changeSettingsWidgetStatus); connect(ui->accelerationComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseSettingsDialog::refreshMouseCursorSpeedValues); connect(ui->mouseModeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseSettingsDialog::changeSpringSectionStatus); connect(ui->mouseModeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseSettingsDialog::changeMouseSpeedBoxStatus); connect(ui->mouseModeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseSettingsDialog::changeWheelSpeedBoxStatus); connect(ui->mouseModeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseSettingsDialog::changeSensitivityStatusForMouseMode); connect(ui->horizontalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseSettingsDialog::updateHorizontalSpeedConvertLabel); connect(ui->horizontalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseSettingsDialog::moveSpeedsTogether); connect(ui->verticalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseSettingsDialog::updateVerticalSpeedConvertLabel); connect(ui->verticalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseSettingsDialog::moveSpeedsTogether); connect(ui->wheelVertSpeedSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseSettingsDialog::updateWheelVerticalSpeedLabel); connect(ui->wheelHoriSpeedSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseSettingsDialog::updateWheelHorizontalSpeedLabel); connect(ui->relativeSpringCheckBox, &QCheckBox::clicked, this, &MouseSettingsDialog::disableReleaseSpringBox); connect(ui->relativeSpringCheckBox, &QCheckBox::clicked, this, &MouseSettingsDialog::resetReleaseRadius); } MouseSettingsDialog::~MouseSettingsDialog() { delete ui; } void MouseSettingsDialog::changeSettingsWidgetStatus(int index) { JoyButton::JoyMouseCurve temp = getMouseCurveForIndex(index); int currentMouseMode = ui->mouseModeComboBox->currentIndex(); if ((currentMouseMode == 1) && (temp == JoyButton::PowerCurve)) { ui->sensitivityDoubleSpinBox->setEnabled(true); } else { ui->sensitivityDoubleSpinBox->setEnabled(false); } if ((currentMouseMode == 1) && ((temp == JoyButton::EasingQuadraticCurve) || (temp == JoyButton::EasingCubicCurve))) { ui->easingDoubleSpinBox->setEnabled(true); } else { ui->easingDoubleSpinBox->setEnabled(false); } } void MouseSettingsDialog::changeSpringSectionStatus(int index) { if (index == 2) { ui->springWidthSpinBox->setEnabled(true); ui->springHeightSpinBox->setEnabled(true); ui->relativeSpringCheckBox->setEnabled(true); bool enableSpringRadiusBox = !ui->relativeSpringCheckBox->isChecked(); ui->releaseSpringRadiusspinBox->setEnabled(enableSpringRadiusBox); } else { ui->springWidthSpinBox->setEnabled(false); ui->springHeightSpinBox->setEnabled(false); ui->relativeSpringCheckBox->setEnabled(false); ui->releaseSpringRadiusspinBox->setEnabled(false); } } void MouseSettingsDialog::updateHorizontalSpeedConvertLabel(int value) { QString label = QString(QString::number(value)); int currentCurveIndex = ui->accelerationComboBox->currentIndex(); JoyButton::JoyMouseCurve tempCurve = getMouseCurveForIndex(currentCurveIndex); int finalSpeed = JoyButton::calculateFinalMouseSpeed(tempCurve, value, GlobalVariables::JoyAxis::JOYSPEED); label = label.append(" = ").append(QString::number(finalSpeed)).append(" pps"); ui->horizontalSpeedLabel->setText(label); } void MouseSettingsDialog::updateVerticalSpeedConvertLabel(int value) { QString label = QString(QString::number(value)); int currentCurveIndex = ui->accelerationComboBox->currentIndex(); JoyButton::JoyMouseCurve tempCurve = getMouseCurveForIndex(currentCurveIndex); int finalSpeed = JoyButton::calculateFinalMouseSpeed(tempCurve, value, GlobalVariables::JoyAxis::JOYSPEED); label = label.append(" = ").append(QString::number(finalSpeed)).append(" pps"); ui->verticalSpeedLabel->setText(label); } void MouseSettingsDialog::moveSpeedsTogether(int value) { if (ui->changeMouseSpeedsTogetherCheckBox->isChecked()) { ui->horizontalSpinBox->setValue(value); ui->verticalSpinBox->setValue(value); } } void MouseSettingsDialog::changeMouseSpeedBoxStatus(int index) { if (index == 2) { ui->horizontalSpinBox->setEnabled(false); ui->verticalSpinBox->setEnabled(false); ui->changeMouseSpeedsTogetherCheckBox->setEnabled(false); ui->extraAccelerationGroupBox->setChecked(false); ui->extraAccelerationGroupBox->setEnabled(false); } else { ui->horizontalSpinBox->setEnabled(true); ui->verticalSpinBox->setEnabled(true); ui->changeMouseSpeedsTogetherCheckBox->setEnabled(true); ui->extraAccelerationGroupBox->setEnabled(true); if (ui->extraAccelerationGroupBox->isChecked()) ui->extraAccelerationGroupBox->setEnabled(true); } } void MouseSettingsDialog::changeWheelSpeedBoxStatus(int index) { if (index == 2) { ui->wheelHoriSpeedSpinBox->setEnabled(false); ui->wheelVertSpeedSpinBox->setEnabled(false); } else { ui->wheelHoriSpeedSpinBox->setEnabled(true); ui->wheelVertSpeedSpinBox->setEnabled(true); } } void MouseSettingsDialog::updateWheelVerticalSpeedLabel(int value) { QString label = QString(QString::number(value)); label.append(" = "); label.append(tr("%n notch(es)/s", "", value)); ui->wheelVertSpeedUnitsLabel->setText(label); } void MouseSettingsDialog::updateWheelHorizontalSpeedLabel(int value) { QString label = QString(QString::number(value)); label.append(" = "); label.append(tr("%n notch(es)/s", "", value)); ui->wheelHoriSpeedUnitsLabel->setText(label); } void MouseSettingsDialog::updateAccelerationCurvePresetComboBox(JoyButton::JoyMouseCurve mouseCurve) { switch (mouseCurve) { case JoyButton::EnhancedPrecisionCurve: { ui->accelerationComboBox->setCurrentIndex(1); break; } case JoyButton::LinearCurve: { ui->accelerationComboBox->setCurrentIndex(2); break; } case JoyButton::QuadraticCurve: { ui->accelerationComboBox->setCurrentIndex(3); break; } case JoyButton::CubicCurve: { ui->accelerationComboBox->setCurrentIndex(4); break; } case JoyButton::QuadraticExtremeCurve: { ui->accelerationComboBox->setCurrentIndex(5); break; } case JoyButton::PowerCurve: { ui->accelerationComboBox->setCurrentIndex(6); break; } case JoyButton::EasingQuadraticCurve: { ui->accelerationComboBox->setCurrentIndex(7); break; } case JoyButton::EasingCubicCurve: { ui->accelerationComboBox->setCurrentIndex(8); break; } } } JoyButton::JoyMouseCurve MouseSettingsDialog::getMouseCurveForIndex(int index) { JoyButton::JoyMouseCurve temp = JoyButton::DEFAULTMOUSECURVE; switch (index) { case 1: { temp = JoyButton::EnhancedPrecisionCurve; break; } case 2: { temp = JoyButton::LinearCurve; break; } case 3: { temp = JoyButton::QuadraticCurve; break; } case 4: { temp = JoyButton::CubicCurve; break; } case 5: { temp = JoyButton::QuadraticExtremeCurve; break; } case 6: { temp = JoyButton::PowerCurve; break; } case 7: { temp = JoyButton::EasingQuadraticCurve; break; } case 8: { temp = JoyButton::EasingCubicCurve; break; } } return temp; } void MouseSettingsDialog::changeSensitivityStatusForMouseMode(int index) { if (index == 2) { ui->sensitivityDoubleSpinBox->setEnabled(false); } else if (index == 1) { int currentCurveIndex = ui->accelerationComboBox->currentIndex(); JoyButton::JoyMouseCurve temp = getMouseCurveForIndex(currentCurveIndex); if (temp == JoyButton::PowerCurve) ui->sensitivityDoubleSpinBox->setEnabled(true); } else { ui->sensitivityDoubleSpinBox->setEnabled(false); } } /** * @brief Update mouse status labels with cursor mouse information provided by * an InputDevice. * @param X distance in pixels * @param Y distance in pixels * @param Time elapsed for generated event */ void MouseSettingsDialog::updateMouseCursorStatusLabels(int mouseX, int mouseY, int elapsed) { if ((lastMouseStatUpdate.elapsed() >= 100) && (elapsed > 0)) { QString tempX("%1 (%2 pps) (%3 ms)"); QString tempY("%1 (%2 pps) (%3 ms)"); ui->mouseStatusXLabel->setText(tempX.arg(mouseX).arg(mouseX * (1000 / elapsed)).arg(elapsed)); ui->mouseStatusYLabel->setText(tempY.arg(mouseY).arg(mouseY * (1000 / elapsed)).arg(elapsed)); lastMouseStatUpdate.start(); } } /** * @brief Update mouse status labels with spring mouse information * provided by an InputDevice. * @param X coordinate of cursor * @param Y coordinate of cursor */ void MouseSettingsDialog::updateMouseSpringStatusLabels(int coordX, int coordY) { if (lastMouseStatUpdate.elapsed() >= 100) { QString tempX("%1"); QString tempY("%1"); ui->mouseStatusXLabel->setText(tempX.arg(coordX)); ui->mouseStatusYLabel->setText(tempY.arg(coordY)); lastMouseStatUpdate.start(); } } void MouseSettingsDialog::refreshMouseCursorSpeedValues(int index) { Q_UNUSED(index); updateHorizontalSpeedConvertLabel(ui->horizontalSpinBox->value()); updateVerticalSpeedConvertLabel(ui->verticalSpinBox->value()); } void MouseSettingsDialog::disableReleaseSpringBox(bool enable) { ui->releaseSpringRadiusspinBox->setEnabled(!enable); } void MouseSettingsDialog::resetReleaseRadius(bool enabled) { if (enabled && (ui->releaseSpringRadiusspinBox->value() > 0)) { ui->releaseSpringRadiusspinBox->setValue(0); } } JoyButton::JoyExtraAccelerationCurve MouseSettingsDialog::getExtraAccelCurveForIndex(int index) { JoyButton::JoyExtraAccelerationCurve temp = JoyButton::LinearAccelCurve; switch (index) { case 1: { temp = JoyButton::LinearAccelCurve; break; } case 2: { temp = JoyButton::EaseOutSineCurve; break; } case 3: { temp = JoyButton::EaseOutQuadAccelCurve; break; } case 4: { temp = JoyButton::EaseOutCubicAccelCurve; break; } } return temp; } void MouseSettingsDialog::updateExtraAccelerationCurvePresetComboBox(JoyButton::JoyExtraAccelerationCurve curve) { int temp = 0; switch (curve) { case JoyButton::LinearAccelCurve: { temp = 1; break; } case JoyButton::EaseOutSineCurve: { temp = 2; break; } case JoyButton::EaseOutQuadAccelCurve: { temp = 3; break; } case JoyButton::EaseOutCubicAccelCurve: { temp = 4; break; } } ui->extraAccelCurveComboBox->setCurrentIndex(temp); } AntiMicroX-antimicrox-b300273/src/gui/mousesettingsdialog.h000066400000000000000000000047121471077622000237730ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MOUSESETTINGSDIALOG_H #define MOUSESETTINGSDIALOG_H #include "joybuttontypes/joybutton.h" #include namespace Ui { class MouseSettingsDialog; } class MouseSettingsDialog : public QDialog { Q_OBJECT public: explicit MouseSettingsDialog(QWidget *parent = nullptr); ~MouseSettingsDialog(); protected: void updateAccelerationCurvePresetComboBox(JoyButton::JoyMouseCurve mouseCurve); void updateExtraAccelerationCurvePresetComboBox(JoyButton::JoyExtraAccelerationCurve curve); JoyButton::JoyMouseCurve getMouseCurveForIndex(int index); JoyButton::JoyExtraAccelerationCurve getExtraAccelCurveForIndex(int index); Ui::MouseSettingsDialog *ui; QElapsedTimer lastMouseStatUpdate; public slots: void changeSettingsWidgetStatus(int index); void changeSpringSectionStatus(int index); void changeMouseSpeedBoxStatus(int index); void changeWheelSpeedBoxStatus(int index); void updateHorizontalSpeedConvertLabel(int value); void updateVerticalSpeedConvertLabel(int value); void moveSpeedsTogether(int value); void updateWheelVerticalSpeedLabel(int value); void updateWheelHorizontalSpeedLabel(int value); void changeSensitivityStatusForMouseMode(int index); void updateMouseCursorStatusLabels(int mouseX, int mouseY, int elapsed); void updateMouseSpringStatusLabels(int coordX, int coordY); virtual void changeMouseMode(int index) = 0; virtual void changeMouseCurve(int index) = 0; private slots: void refreshMouseCursorSpeedValues(int index); void disableReleaseSpringBox(bool enable); void resetReleaseRadius(bool enabled); }; #endif // MOUSESETTINGSDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/mousesettingsdialog.ui000066400000000000000000001012651471077622000241620ustar00rootroot00000000000000 MouseSettingsDialog Qt::WindowModal 0 0 587 612 Mouse Settings Mouse Mode: Cursor mode is used to move the mouse cursor around the screen relative to its current position depending on how much you move an axis or if a button is pressed. Spring mode is used to move the mouse cursor from the center of the screen depending on how much you move an axis. The mouse cursor will be returned to the center of the screen when the axis is moved back to the dead zone. Cursor Spring 160 0 Acceleration: Enhanced: Three tier curve that makes the mouse move slow on the low end of an axis and fast on the high end. Linear: Mouse moves proportionally to axis. Quadratic: Mouse accelerates slowly on low end. Cubic: Mouse accelerates slower than Quadratic. Quadratic Extreme: Raises mouse speed 1.5 times once 95% axis travel has been reached. Power Function: Allows for a more custom curve option. Easing Quadratic: Axis high end is gradually accelerated over a period of time using a Quadratic curve. Easing Cubic: Axis high end is gradually accelerated over a period of time using a Cubic curve. Enhanced Precision Linear Quadratic Cubic Quadratic Extreme Power Function Easing Quadratic Easing Cubic Qt::Vertical QSizePolicy::Fixed 20 10 Mouse Speed Settings false false true Enable to change the horizontal and vertical speed boxes at the same time. Change Together 16 10 10 10 Hori&zontal Speed: horizontalSpinBox true 1 1 1 = 20 pps 10 10 &Vertical Speed: verticalSpinBox true 1 1 1 = 20 pps 16 10 10 Wheel Hori. Speed: wheelHoriSpeedSpinBox Set the speed used for horizontal mouse wheel movement according to number of simulated notches per second. 1 100 1 1 1 = 1 notch(es)/s 10 Wheel Vert. Speed: wheelVertSpeedSpinBox Set the speed used for vertical mouse wheel movement according to number of simulated notches per second. 1 100 1 = 1 notch(es)/s Sensitivit&y: sensitivityDoubleSpinBox false For Power Function acceleration curve. Specifies the factor to use for curve sensitivity. When the value is above 1.0, the mouse movement will be accelerated faster at the low end of an axis. 3 0.001000000000000 1000.000000000000000 0.100000000000000 1.000000000000000 Easing Duration: sensitivityDoubleSpinBox false Specifies the amount of time (in seconds) that will be required before the mouse is fully accelerated after reaching the high end of an axis. s 2 0.000000000000000 5.000000000000000 0.100000000000000 0.500000000000000 Qt::Vertical QSizePolicy::Fixed 20 10 true Options for adding more acceleration to the mouse movement beyond what the acceleration curve would produce. Acceleration is added based on how quickly an axis is moved in one gamepad poll. This is meant to help work around some of the issues of the very limited input range available using typical gamepad analog sticks. Delta Acceleration false true false &Multiplier: extraAccelDoubleSpinBox Highest value to accelerate mouse movement by x 1.000000000000000 200.000000000000000 2.000000000000000 Start %: minMultiDoubleSpinBox Acceleration begins at this percentage of the base multiplier % 0.000000000000000 100.000000000000000 1.000000000000000 0.000000000000000 Mi&n Threshold: minThresholdDoubleSpinBox Minimum amount of axis travel required for acceleration to begin % 100.000000000000000 10.000000000000000 Max Threshold: maxThresholdDoubleSpinBox Maximum axis travel before acceleration has reached the multiplier value % 100.000000000000000 100.000000000000000 E&xtra Duration: accelExtraDurationDoubleSpinBox Extend the time that extra acceleration is applied. Axis travel will be taken into account. A slower flick will decrease the actual time that extra acceleration will be applied. s 0.000000000000000 5.000000000000000 0.050000000000000 Curve: Linear Ease Out Sine Ease Out Quad Ease Out Cubic 10 Spring Settings Spring Width: springWidthSpinBox false Changes the width of the region that the cursor can move in spring mode. 0 will use the entire width of your screen. 16777215 Spring Height: springHeightSpinBox false Changes the height of the region that the cursor can move in spring mode. 0 will use the entire height of your screen. 16777215 Release Radius: releaseSpringRadiusspinBox false % 100 false Specifies that the spring area will be relative to the mouse position set by a non-relative spring. Relative Qt::Vertical 20 40 Mouse Status X: 0 (0 pps) Y: 0 (0 pps) Qt::Vertical QSizePolicy::Fixed 20 10 Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() MouseSettingsDialog accept() 248 254 157 274 buttonBox rejected() MouseSettingsDialog reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/qkeydisplaydialog.cpp000066400000000000000000000066031471077622000237550ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "qkeydisplaydialog.h" #include "ui_qkeydisplaydialog.h" #include "antkeymapper.h" #include "eventhandlerfactory.h" #include #include #include #include #include #ifdef WITH_X11 #include "x11extras.h" #endif #ifdef Q_OS_WIN #include "winextras.h" #endif QKeyDisplayDialog::QKeyDisplayDialog(QWidget *parent) : QDialog(parent) , ui(new Ui::QKeyDisplayDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); this->setFocus(); BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); ui->eventHandlerLabel->setText(handler->getName()); } QKeyDisplayDialog::~QKeyDisplayDialog() { delete ui; } void QKeyDisplayDialog::keyPressEvent(QKeyEvent *event) { switch (event->key()) { case Qt::Key_Escape: case Qt::Key_Enter: case Qt::Key_Return: break; default: QDialog::keyPressEvent(event); } } void QKeyDisplayDialog::keyReleaseEvent(QKeyEvent *event) { int scancode = event->nativeScanCode(); int virtualkey = event->nativeVirtualKey(); int finalvirtual = 0; #ifdef Q_OS_WIN finalvirtual = WinExtras::correctVirtualKey(scancode, virtualkey); unsigned int tempvirtual = finalvirtual; #elif defined WITH_X11 if (QApplication::platformName() == QStringLiteral("xcb")) { // Obtain group 1 X11 keysym. Removes effects from modifiers. finalvirtual = X11Extras::getInstance()->getGroup1KeySym(virtualkey); #ifdef WITH_UINPUT QtKeyMapperBase *nativeKeyMapper = AntKeyMapper::getInstance()->getNativeKeyMapper(); if (nativeKeyMapper && (nativeKeyMapper->getIdentifier() == "xtest")) { int tempalias = nativeKeyMapper->returnQtKey(virtualkey); finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey(tempalias); } #endif } else { finalvirtual = scancode; } #else if (QApplication::platformName() == QStringLiteral("xcb")) { finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey(event->key()); } else { finalvirtual = scancode; } #endif ui->nativeKeyLabel->setText(QString("0x%1").arg(finalvirtual, 0, 16)); ui->qtKeyLabel->setText(QString("0x%1").arg(event->key(), 0, 16)); #ifdef Q_OS_WIN QString tempValue = QString("0x%1").arg(AntKeyMapper::getInstance()->returnQtKey(tempvirtual, scancode), 0, 16); #else QString tempValue = QString("0x%1").arg(AntKeyMapper::getInstance()->returnQtKey(finalvirtual), 0, 16); #endif ui->antimicroKeyLabel->setText(tempValue); } AntiMicroX-antimicrox-b300273/src/gui/qkeydisplaydialog.h000066400000000000000000000024461471077622000234230ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef QKEYDISPLAYDIALOG_H #define QKEYDISPLAYDIALOG_H #include class QKeyEvent; class QWidget; namespace Ui { class QKeyDisplayDialog; } class QKeyDisplayDialog : public QDialog { Q_OBJECT public: explicit QKeyDisplayDialog(QWidget *parent = nullptr); ~QKeyDisplayDialog(); protected: virtual void keyPressEvent(QKeyEvent *event); virtual void keyReleaseEvent(QKeyEvent *event); private: Ui::QKeyDisplayDialog *ui; }; #endif // QKEYDISPLAYDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/qkeydisplaydialog.ui000066400000000000000000000157241471077622000236140ustar00rootroot00000000000000 QKeyDisplayDialog Qt::ApplicationModal 0 0 597 428 0 0 Qt::StrongFocus Key Checker true 8 8 <html><head/><body><p>Press a key on your keyboard to see how the key is detected by this application. The window will show the system native key value, the original value given by Qt (if applicable), and the custom value used by AntiMicroX.</p><p>The AntiMicroX key value and the Qt key value will usually be the same. AntiMicroX tries to use the key values defined in Qt when possible. Check the page <a href="http://doc.qt.io/qt-5/qt.html#Key-enum"><span style=" text-decoration: underline; color:#0057ae;">http://doc.qt.io/qt-5/qt.html#Key-enum</span></a> for a list of values defined by Qt. If you discover that a key is not natively supported by this program, please report the problem to AntiMicroX's <a href="https://github.com/AntiMicroX/antimicrox/"><span style=" text-decoration: underline; color:#0057ae;">GitHub page</span></a> so that the program can be edited to support it directly. As it is, a custom prefix is added to unknown values so they can still be used; the main problem is that the profile will no longer be portable.</p></body></html> Qt::AutoText true true Qt::LinksAccessibleByMouse Qt::Vertical QSizePolicy::Fixed 20 10 QFormLayout::ExpandingFieldsGrow 20 10 6 10 75 true Event Handler: 75 true Native Key Value: 0x00000000 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse 75 true Qt Key Value: 0x00000000 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse 75 true antimicro Key Value: 0x00000000 Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse Qt::NoFocus Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() QKeyDisplayDialog accept() 248 254 157 274 buttonBox rejected() QKeyDisplayDialog reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/quicksetdialog.cpp000066400000000000000000000410441471077622000232440ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "quicksetdialog.h" #include "ui_quicksetdialog.h" #include "buttoneditdialog.h" #include "inputdevice.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joybuttontypes/joydpadbutton.h" #include "joycontrolstick.h" #include "joydpad.h" #include "setjoystick.h" #include "uihelpers/buttoneditdialoghelper.h" #include "vdpad.h" #include #include #include #include #include QuickSetDialog::QuickSetDialog(InputDevice *joystick, QWidget *parent) : QDialog(parent) , ui(new Ui::QuickSetDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); this->joystick = joystick; this->currentButtonDialog = nullptr; setWindowTitle(tr("Quick Set %1").arg(joystick->getName())); SetJoystick *currentset = joystick->getActiveSetJoystick(); currentset->release(); joystick->resetButtonDownCount(); QString temp = ui->joystickDialogLabel->text(); temp = temp.arg(joystick->getSDLName()).arg(joystick->getName()); ui->joystickDialogLabel->setText(temp); connectSticksForDialog(currentset); connectAxesForDialog(currentset); connectDpadForDialog(currentset); connectVDpadForDialog(currentset); connectBtnForDialog(currentset); connect(this, &QuickSetDialog::finished, this, &QuickSetDialog::restoreJoystickState); } QuickSetDialog::QuickSetDialog(InputDevice *joystick, ButtonEditDialogHelper *helper, const char *invokeString, int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode, bool withClear, bool withTrue, QWidget *parent) : QDialog(parent) , ui(new Ui::QuickSetDialog) { ui->setupUi(this); show(); this->joystick = joystick; this->invokeString = invokeString; this->code = code; this->alias = alias; this->index = index; this->mode = mode; this->withClear = withClear; this->withTrue = withTrue; this->helper = helper; lastButton = nullptr; setWindowTitle(tr("Quick Set %1").arg(joystick->getName())); setAttribute(Qt::WA_DeleteOnClose); setWindowModality(Qt::WindowModal); SetJoystick *currentset = joystick->getActiveSetJoystick(); QString temp = ui->joystickDialogLabel->text(); temp = temp.arg(joystick->getSDLName()).arg(joystick->getName()); ui->joystickDialogLabel->setText(temp); connectSticksForDialog(currentset); connectAxesForDialog(currentset); connectDpadForDialog(currentset); connectVDpadForDialog(currentset); connectBtnForDialog(currentset); connect(this, &QuickSetDialog::finished, this, &QuickSetDialog::restoreJoystickState); } void QuickSetDialog::connectSticksForDialog(SetJoystick *currentset) { QListIterator sticksList = currentset->getSticks().values(); while (sticksList.hasNext()) { JoyControlStick *stick = sticksList.next(); QHash *stickButtons = stick->getButtons(); QHashIterator iter(*stickButtons); while (iter.hasNext()) { JoyControlStickButton *stickbutton = iter.next().value(); if (stick->getJoyMode() != JoyControlStick::EightWayMode) { if ((stickbutton->getJoyNumber() != static_cast(JoyControlStick::StickLeftUp)) && (stickbutton->getJoyNumber() != static_cast(JoyControlStick::StickRightUp)) && (stickbutton->getJoyNumber() != static_cast(JoyControlStick::StickLeftDown)) && (stickbutton->getJoyNumber() != static_cast(JoyControlStick::StickRightDown))) { connect(stickbutton, &JoyControlStickButton::clicked, this, [this, stickbutton]() { showStickButtonDialog(stickbutton); }); } } else { connect(stickbutton, &JoyControlStickButton::clicked, this, [this, stickbutton]() { showStickButtonDialog(stickbutton); }); } if (!stickbutton->getIgnoreEventState()) stickbutton->setIgnoreEventState(true); } } } void QuickSetDialog::connectAxesForDialog(SetJoystick *currentset) { QListIterator axesList = currentset->getAxes()->values(); while (axesList.hasNext()) { JoyAxis *axis = axesList.next(); if (!axis->isPartControlStick() && axis->hasControlOfButtons()) { JoyAxisButton *naxisbutton = axis->getNAxisButton(); JoyAxisButton *paxisbutton = axis->getPAxisButton(); connect(naxisbutton, &JoyAxisButton::clicked, this, [this, naxisbutton]() { showAxisButtonDialog(naxisbutton); }); connect(paxisbutton, &JoyAxisButton::clicked, this, [this, paxisbutton]() { showAxisButtonDialog(paxisbutton); }); if (!naxisbutton->getIgnoreEventState()) naxisbutton->setIgnoreEventState(true); if (!paxisbutton->getIgnoreEventState()) paxisbutton->setIgnoreEventState(true); } } } void QuickSetDialog::connectDpadForDialog(SetJoystick *currentset) { QListIterator dpadsList = currentset->getHats().values(); while (dpadsList.hasNext()) { JoyDPad *dpad = dpadsList.next(); QHash *dpadbuttons = dpad->getButtons(); QHashIterator iter(*dpadbuttons); while (iter.hasNext()) { JoyDPadButton *dpadbutton = iter.next().value(); if (dpad->getJoyMode() != JoyDPad::EightWayMode) { if ((dpadbutton->getJoyNumber() != JoyDPadButton::DpadLeftUp) && (dpadbutton->getJoyNumber() != JoyDPadButton::DpadRightUp) && (dpadbutton->getJoyNumber() != JoyDPadButton::DpadLeftDown) && (dpadbutton->getJoyNumber() != JoyDPadButton::DpadRightDown)) { connect(dpadbutton, &JoyDPadButton::clicked, this, [this, dpadbutton] { showDPadButtonDialog(dpadbutton); }); } } else { connect(dpadbutton, &JoyDPadButton::clicked, this, [this, dpadbutton] { showDPadButtonDialog(dpadbutton); }); } if (!dpadbutton->getIgnoreEventState()) dpadbutton->setIgnoreEventState(true); } } } void QuickSetDialog::connectVDpadForDialog(SetJoystick *currentset) { QListIterator vdpadsList = currentset->getVdpads().values(); while (vdpadsList.hasNext()) { VDPad *dpad = vdpadsList.next(); if (dpad != nullptr) { QHash *dpadbuttons = dpad->getButtons(); QHashIterator iter(*dpadbuttons); while (iter.hasNext()) { JoyDPadButton *dpadbutton = iter.next().value(); if (dpad->getJoyMode() != JoyDPad::EightWayMode) { if ((dpadbutton->getJoyNumber() != JoyDPadButton::DpadLeftUp) && (dpadbutton->getJoyNumber() != JoyDPadButton::DpadRightUp) && (dpadbutton->getJoyNumber() != JoyDPadButton::DpadLeftDown) && (dpadbutton->getJoyNumber() != JoyDPadButton::DpadRightDown)) { connect(dpadbutton, &JoyDPadButton::clicked, this, [this, dpadbutton] { showDPadButtonDialog(dpadbutton); }); } } else { connect(dpadbutton, &JoyDPadButton::clicked, this, [this, dpadbutton] { showDPadButtonDialog(dpadbutton); }); } if (!dpadbutton->getIgnoreEventState()) dpadbutton->setIgnoreEventState(true); } } } } void QuickSetDialog::connectBtnForDialog(SetJoystick *currentset) { QListIterator btnsList = currentset->getButtons().values(); while (btnsList.hasNext()) { JoyButton *button = btnsList.next(); if ((button != nullptr) && !button->isPartVDPad()) { connect(button, &JoyButton::clicked, this, [this, button] { showButtonDialog(button); }); if (!button->getIgnoreEventState()) button->setIgnoreEventState(true); } } } QuickSetDialog::~QuickSetDialog() { delete ui; } void QuickSetDialog::invokeMethodLastBtn(JoyButton *lastJoyBtn, Qt::ConnectionType connTypeForAlias, Qt::ConnectionType connTypeForNothing, Qt::ConnectionType connTypeForAll, bool possibleAxisAction) { lastButton = lastJoyBtn; // sometimes appears situation, when we want to map an axis of stick, // it's detected some state between pressing stick button and moving axis. // It chooses a function for pressing a stick, but later appears a problem, // because correct and prepared value is from the axis one, so static_cast // for stick button is failing // App can sometimes ask to three times for a button, but it's not going to crash this time // if lastButton is still a null pointer, check possible value correctness coming from axis if (possibleAxisAction && (lastButton == nullptr)) lastButton = qobject_cast(sender()); if (helper != nullptr) helper = new ButtonEditDialogHelper(); if (lastButton != nullptr) { helper->setThisButton(lastButton); helper->moveToThread(lastButton->thread()); if (withClear) QMetaObject::invokeMethod(lastButton, "clearSlotsEventReset", Q_ARG(bool, withTrue)); // when alias exists but not index if ((alias != -1) && (index == -1)) { QMetaObject::invokeMethod(helper, invokeString, connTypeForAlias, Q_ARG(int, code), Q_ARG(int, alias), Q_ARG(JoyButtonSlot::JoySlotInputAction, mode)); // when alias doesn't exists and index too } else if ((alias == -1) && (index == -1)) { QMetaObject::invokeMethod(helper, invokeString, connTypeForNothing, Q_ARG(int, code), Q_ARG(JoyButtonSlot::JoySlotInputAction, mode)); // when all exist (code, alias, index) } else { QMetaObject::invokeMethod(helper, invokeString, connTypeForAll, Q_ARG(int, code), Q_ARG(int, alias), Q_ARG(int, index), Q_ARG(JoyButtonSlot::JoySlotInputAction, mode)); } } } void QuickSetDialog::showAxisButtonDialog(JoyAxisButton *joybtn) { invokeMethodLastBtn(joybtn, Qt::QueuedConnection, Qt::QueuedConnection, Qt::QueuedConnection); this->close(); } void QuickSetDialog::showButtonDialog(JoyButton *joybtn) { invokeMethodLastBtn(joybtn, Qt::QueuedConnection, Qt::QueuedConnection, Qt::QueuedConnection); this->close(); } void QuickSetDialog::showStickButtonDialog(JoyControlStickButton *joyctrlstickbtn) { lastButton = joyctrlstickbtn; invokeMethodLastBtn(joyctrlstickbtn, Qt::QueuedConnection, Qt::QueuedConnection, Qt::QueuedConnection, true); this->close(); } void QuickSetDialog::showDPadButtonDialog(JoyDPadButton *joydpadbtn) { invokeMethodLastBtn(joydpadbtn, Qt::QueuedConnection, Qt::QueuedConnection, Qt::BlockingQueuedConnection); this->close(); } void QuickSetDialog::restoreJoystickState() { SetJoystick *currentset = joystick->getActiveSetJoystick(); restoreSticksStates(currentset); restoreAxesStates(currentset); restoreHatsStates(currentset); restoreVDPadsStates(currentset); restoreButtonsStates(currentset); currentset->release(); } void QuickSetDialog::restoreSticksStates(SetJoystick *currentset) { QListIterator sticksList = currentset->getSticks().values(); while (sticksList.hasNext()) { JoyControlStick *stick = sticksList.next(); QHash *stickButtons = stick->getButtons(); QHashIterator iter(*stickButtons); while (iter.hasNext()) { JoyControlStickButton *stickbutton = iter.next().value(); if (stickbutton->getIgnoreEventState()) stickbutton->setIgnoreEventState(false); disconnect(stickbutton, &JoyControlStickButton::clicked, this, nullptr); } } } void QuickSetDialog::restoreAxesStates(SetJoystick *currentset) { QListIterator axesList = currentset->getAxes()->values(); while (axesList.hasNext()) { JoyAxis *axis = axesList.next(); if (!axis->isPartControlStick() && axis->hasControlOfButtons()) { JoyAxisButton *naxisbutton = axis->getNAxisButton(); if (naxisbutton->getIgnoreEventState()) naxisbutton->setIgnoreEventState(false); JoyAxisButton *paxisbutton = axis->getPAxisButton(); if (paxisbutton->getIgnoreEventState()) paxisbutton->setIgnoreEventState(false); disconnect(naxisbutton, &JoyAxisButton::clicked, this, nullptr); disconnect(paxisbutton, &JoyAxisButton::clicked, this, nullptr); } } } void QuickSetDialog::restoreHatsStates(SetJoystick *currentset) { QListIterator hatsList = currentset->getHats().values(); while (hatsList.hasNext()) { JoyDPad *dpad = hatsList.next(); QHash *dpadbuttons = dpad->getButtons(); QHashIterator iter(*dpadbuttons); while (iter.hasNext()) { JoyDPadButton *dpadbutton = iter.next().value(); if (dpadbutton->getIgnoreEventState()) dpadbutton->setIgnoreEventState(false); disconnect(dpadbutton, &JoyDPadButton::clicked, this, nullptr); } } } void QuickSetDialog::restoreVDPadsStates(SetJoystick *currentset) { QListIterator vdpadsList = currentset->getVdpads().values(); while (vdpadsList.hasNext()) { VDPad *dpad = vdpadsList.next(); if (dpad != nullptr) { QHash *dpadbuttons = dpad->getButtons(); QHashIterator iter(*dpadbuttons); while (iter.hasNext()) { JoyDPadButton *dpadbutton = iter.next().value(); if (dpadbutton->getIgnoreEventState()) dpadbutton->setIgnoreEventState(false); disconnect(dpadbutton, &JoyDPadButton::clicked, this, nullptr); } } } } void QuickSetDialog::restoreButtonsStates(SetJoystick *currentset) { QListIterator btnsList = currentset->getButtons().values(); while (btnsList.hasNext()) { JoyButton *button = btnsList.next(); if ((button != nullptr) && !button->isPartVDPad()) { if (button->getIgnoreEventState()) button->setIgnoreEventState(false); disconnect(button, &JoyButton::clicked, this, nullptr); } } } JoyButton *QuickSetDialog::getLastPressedButton() const { return lastButton; } InputDevice *QuickSetDialog::getJoystick() const { return joystick; } QDialog *QuickSetDialog::getCurrentButtonDialog() const { return currentButtonDialog; } const char *QuickSetDialog::getInvokeString() const { return invokeString; } ButtonEditDialogHelper *QuickSetDialog::getHelper() const { return helper; } JoyButtonSlot::JoySlotInputAction QuickSetDialog::getMode() const { return mode; } AntiMicroX-antimicrox-b300273/src/gui/quicksetdialog.h000066400000000000000000000072771471077622000227230ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef QUICKSETDIALOG_H #define QUICKSETDIALOG_H #include "uihelpers/buttoneditdialoghelper.h" #include class InputDevice; class QWidget; class SetJoystick; class JoyControlStick; class JoyButton; class JoyControlStickButton; class JoyDPadButton; class JoyAxisButton; namespace Ui { class QuickSetDialog; } class QuickSetDialog : public QDialog { Q_OBJECT public: explicit QuickSetDialog(InputDevice *joystick, QWidget *parent = nullptr); QuickSetDialog(InputDevice *joystick, ButtonEditDialogHelper *helper, const char *invokeString, int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode, bool withClear, bool withTrue, QWidget *parent = nullptr); ~QuickSetDialog(); JoyButton *getLastPressedButton() const; InputDevice *getJoystick() const; QDialog *getCurrentButtonDialog() const; const char *getInvokeString() const; ButtonEditDialogHelper *getHelper() const; JoyButtonSlot::JoySlotInputAction getMode() const; private slots: void showAxisButtonDialog(JoyAxisButton *joybtn); // QuickSetDialogAxisBtn class void showButtonDialog(JoyButton *joybtn); // QuickSetDialogBtn class void showStickButtonDialog(JoyControlStickButton *joyctrlstickbtn); // QuickSetDialogStick class void showDPadButtonDialog(JoyDPadButton *joydpadbtn); // QuickSetDialogHat class void restoreJoystickState(); private: void invokeMethodLastBtn(JoyButton *lastJoyBtn, Qt::ConnectionType connTypeForAlias, Qt::ConnectionType connTypeForNothing, Qt::ConnectionType connTypeForAll, bool possibleAxisAction = false); void restoreSticksStates(SetJoystick *currentset); // QuickSetDialogStick class void restoreAxesStates(SetJoystick *currentset); // QuickSetDialogAxis class void restoreHatsStates(SetJoystick *currentset); // QuickSetDialogHat class void restoreVDPadsStates(SetJoystick *currentset); // QuickSetDialogVDPad class void restoreButtonsStates(SetJoystick *currentset); // QuickSetDialogBtn class void connectSticksForDialog(SetJoystick *currentset); // QuickSetDialogStick class void connectAxesForDialog(SetJoystick *currentset); // QuickSetDialogAxis class void connectDpadForDialog(SetJoystick *currentset); // QuickSetDialogHat class void connectVDpadForDialog(SetJoystick *currentset); // QuickSetDialogVDPad class void connectBtnForDialog(SetJoystick *currentset); // QuickSetDialogBtn class Ui::QuickSetDialog *ui; InputDevice *joystick; QDialog *currentButtonDialog; ButtonEditDialogHelper *helper; JoyButton *lastButton; const char *invokeString; int code; int alias; int index; JoyButtonSlot::JoySlotInputAction mode; bool withClear; bool withTrue; }; #endif // QUICKSETDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/quicksetdialog.ui000066400000000000000000000040761471077622000231030ustar00rootroot00000000000000 QuickSetDialog 0 0 400 300 Quick Set true <html><head/><body><p>Please press a button or move an axis on %1 (<span style=" font-weight:600;">%2</span>).<br/>A dialog window will then appear which will<br/>allow you to make an assignment.</p></body></html> Qt::AlignCenter false Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() QuickSetDialog accept() 248 254 157 274 buttonBox rejected() QuickSetDialog reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/setaxisthrottledialog.cpp000066400000000000000000000033361471077622000246640ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "setaxisthrottledialog.h" #include "ui_setaxisthrottledialog.h" #include "joyaxis.h" #include #include SetAxisThrottleDialog::SetAxisThrottleDialog(JoyAxis *axis, QWidget *parent) : QDialog(parent) , ui(new Ui::SetAxisThrottleDialog) { ui->setupUi(this); this->axis = axis; QString currentText = ui->label->text(); currentText = currentText.arg(QString::number(axis->getRealJoyIndex())); ui->label->setText(currentText); connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &SetAxisThrottleDialog::propogateThrottleChange); connect(this, &SetAxisThrottleDialog::initiateSetAxisThrottleChange, axis, &JoyAxis::propogateThrottleChange); } SetAxisThrottleDialog::~SetAxisThrottleDialog() { delete ui; } void SetAxisThrottleDialog::propogateThrottleChange() { emit initiateSetAxisThrottleChange(); } JoyAxis *SetAxisThrottleDialog::getAxis() const { return axis; } AntiMicroX-antimicrox-b300273/src/gui/setaxisthrottledialog.h000066400000000000000000000025761471077622000243360ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SETAXISTHROTTLEDIALOG_H #define SETAXISTHROTTLEDIALOG_H #include class JoyAxis; class QWidget; namespace Ui { class SetAxisThrottleDialog; } class SetAxisThrottleDialog : public QDialog { Q_OBJECT public: explicit SetAxisThrottleDialog(JoyAxis *axis, QWidget *parent = nullptr); ~SetAxisThrottleDialog(); JoyAxis *getAxis() const; signals: void initiateSetAxisThrottleChange(); private slots: void propogateThrottleChange(); private: Ui::SetAxisThrottleDialog *ui; JoyAxis *axis; }; #endif // SETAXISTHROTTLEDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/setaxisthrottledialog.ui000066400000000000000000000035411471077622000245150ustar00rootroot00000000000000 SetAxisThrottleDialog 0 0 400 207 Throttle Change The throttle setting for Axis %1 has been changed. Would you like to distribute this throttle change to all sets? Qt::AlignCenter Qt::Horizontal QDialogButtonBox::No|QDialogButtonBox::Yes false buttonBox accepted() SetAxisThrottleDialog accept() 248 254 157 274 buttonBox rejected() SetAxisThrottleDialog reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/setnamesdialog.cpp000066400000000000000000000041571471077622000232370ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "setnamesdialog.h" #include "ui_setnamesdialog.h" #include "globalvariables.h" #include "inputdevice.h" #include #include #include SetNamesDialog::SetNamesDialog(InputDevice *device, QWidget *parent) : QDialog(parent) , ui(new Ui::SetNamesDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); this->device = device; auto joysList = device->getJoystick_sets(); for (int i = 0; i < joysList.size(); i++) { auto name = joysList[i]->getName(); ui->setNamesTableWidget->setItem(i, 0, new QTableWidgetItem(name)); } connect(this, &SetNamesDialog::accepted, this, &SetNamesDialog::saveSetNameChanges); } SetNamesDialog::~SetNamesDialog() { delete ui; } void SetNamesDialog::saveSetNameChanges() { for (int i = 0; i < ui->setNamesTableWidget->rowCount(); i++) { QTableWidgetItem *setNameItem = ui->setNamesTableWidget->item(i, 0); QString setNameText = setNameItem->text(); QString oldSetNameText = device->getSetJoystick(i)->getName(); if (setNameText != oldSetNameText) qDebug() << "Set number: " << i << " Renamed to: " << setNameText; device->getSetJoystick(i)->setName(setNameText); } } InputDevice *SetNamesDialog::getDevice() const { return device; } AntiMicroX-antimicrox-b300273/src/gui/setnamesdialog.h000066400000000000000000000024411471077622000226760ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SETNAMESDIALOG_H #define SETNAMESDIALOG_H #include class InputDevice; class QWidget; namespace Ui { class SetNamesDialog; } class SetNamesDialog : public QDialog { Q_OBJECT public: explicit SetNamesDialog(InputDevice *device, QWidget *parent = nullptr); ~SetNamesDialog(); InputDevice *getDevice() const; private: Ui::SetNamesDialog *ui; InputDevice *device; private slots: void saveSetNameChanges(); }; #endif // SETNAMESDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/setnamesdialog.ui000066400000000000000000000076111471077622000230700ustar00rootroot00000000000000 SetNamesDialog 0 0 535 399 Set Name Settings true 1 QAbstractItemView::SingleSelection true Qt::SolidLine false true false true true true 30 18 Set 1 Set 2 Set 3 Set 4 Set 5 Set 6 Set 7 Set 8 Name Qt::Vertical QSizePolicy::Fixed 20 20 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() SetNamesDialog accept() 248 254 157 274 buttonBox rejected() SetNamesDialog reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/slotitemlistwidget.cpp000066400000000000000000000035441471077622000241770ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "slotitemlistwidget.h" #include "simplekeygrabberbutton.h" #include #include #include #include SlotItemListWidget::SlotItemListWidget(QWidget *parent) : QListWidget(parent) { } void SlotItemListWidget::insertItems(int row, QList items) { for (auto el : items) { insertItem(row, el); row++; } } void SlotItemListWidget::keyPressEvent(QKeyEvent *event) { bool propogate = true; QListWidgetItem *currentItem = this->item(this->currentRow()); SimpleKeyGrabberButton *tempbutton = nullptr; if (currentItem != nullptr) tempbutton = currentItem->data(Qt::UserRole).value(); if (tempbutton != nullptr && tempbutton->isGrabbing()) { switch (event->key()) { case Qt::Key_Home: case Qt::Key_End: { propogate = false; break; } default: break; } } if (propogate) QListWidget::keyPressEvent(event); } AntiMicroX-antimicrox-b300273/src/gui/slotitemlistwidget.h000066400000000000000000000023161471077622000236400ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SLOTITEMLISTWIDGET_H #define SLOTITEMLISTWIDGET_H #include class QWidget; class QKeyEvent; class SlotItemListWidget : public QListWidget { Q_OBJECT public: explicit SlotItemListWidget(QWidget *parent = nullptr); void insertItems(int row, QList items); protected: virtual void keyPressEvent(QKeyEvent *event); }; #endif // SLOTITEMLISTWIDGET_H AntiMicroX-antimicrox-b300273/src/gui/unixwindowinfodialog.cpp000066400000000000000000000067761471077622000245200ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "ui_unixwindowinfodialog.h" #include "unixwindowinfodialog.h" #include "x11info.h" UnixWindowInfoDialog::UnixWindowInfoDialog(unsigned long window, QWidget *parent) : QDialog(parent) , ui(new Ui::UnixWindowInfoDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); X11Info *info = X11Info::getInstance(); bool setRadioDefault = false; winClass = info->getWindowClass(window); ui->winClassLabel->setText(winClass); if (winClass.isEmpty()) { ui->winClassCheckBox->setEnabled(false); ui->winClassCheckBox->setChecked(false); } else { ui->winClassCheckBox->setChecked(true); setRadioDefault = true; } winName = info->getWindowTitle(window); ui->winTitleLabel->setText(winName); if (winName.isEmpty()) { ui->winTitleCheckBox->setEnabled(false); ui->winTitleCheckBox->setChecked(false); } else if (!setRadioDefault) { ui->winTitleCheckBox->setChecked(true); setRadioDefault = true; } ui->winPathLabel->clear(); int pid = info->getApplicationPid(window); if (pid > 0) { QString exepath = X11Info::getInstance()->getApplicationLocation(pid); if (!exepath.isEmpty()) { ui->winPathLabel->setText(exepath); winPath = exepath; if (!setRadioDefault) { ui->winTitleCheckBox->setChecked(true); setRadioDefault = true; } } else { ui->winPathCheckBox->setEnabled(false); ui->winPathCheckBox->setChecked(false); } } else { ui->winPathCheckBox->setEnabled(false); ui->winPathCheckBox->setChecked(false); } if (winClass.isEmpty() && winName.isEmpty() && winPath.isEmpty()) { QPushButton *button = ui->buttonBox->button(QDialogButtonBox::Ok); button->setEnabled(false); } connect(this, SIGNAL(accepted()), this, SLOT(populateOption())); } void UnixWindowInfoDialog::populateOption() { if (ui->winClassCheckBox->isChecked()) { selectedMatch = selectedMatch | WindowClass; } if (ui->winTitleCheckBox->isChecked()) { selectedMatch = selectedMatch | WindowName; } if (ui->winPathCheckBox->isChecked()) { selectedMatch = selectedMatch | WindowPath; } } UnixWindowInfoDialog::DialogWindowOption UnixWindowInfoDialog::getSelectedOptions() const { return selectedMatch; } QString UnixWindowInfoDialog::getWindowClass() const { return winClass; } QString UnixWindowInfoDialog::getWindowName() const { return winName; } QString UnixWindowInfoDialog::getWindowPath() const { return winPath; } UnixWindowInfoDialog::~UnixWindowInfoDialog() { delete ui; } AntiMicroX-antimicrox-b300273/src/gui/unixwindowinfodialog.h000066400000000000000000000032231471077622000241450ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef UNIXWINDOWINFODIALOG_H #define UNIXWINDOWINFODIALOG_H #include #include namespace Ui { class UnixWindowInfoDialog; } class UnixWindowInfoDialog : public QDialog { Q_OBJECT public: explicit UnixWindowInfoDialog(long window, QWidget *parent = nullptr); ~UnixWindowInfoDialog(); enum { WindowClass = (1 << 0), WindowName = (1 << 1), WindowPath = (1 << 2) }; typedef int DialogWindowOption; QString getWindowClass() const; QString getWindowName() const; QString getWindowPath() const; DialogWindowOption getSelectedOptions() const; private: Ui::UnixWindowInfoDialog *ui; DialogWindowOption selectedMatch; QString winClass; QString winName; QString winPath; private slots: void populateOption(); }; #endif // UNIXWINDOWINFODIALOG_H AntiMicroX-antimicrox-b300273/src/gui/unixwindowinfodialog.ui000066400000000000000000000123141471077622000243340ustar00rootroot00000000000000 UnixWindowInfoDialog 0 0 533 333 Captured Window Properties 20 50 false Information About Window true 20 Class: true TextLabel Title: true TextLabel Path: true TextLabel Match By Properties true false false Class Title Path Qt::Vertical 20 40 Qt::Horizontal Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() UnixWindowInfoDialog accept() 248 254 157 274 buttonBox rejected() UnixWindowInfoDialog reject() 316 260 286 274 AntiMicroX-antimicrox-b300273/src/gui/winappprofiletimerdialog.cpp000077500000000000000000000013031471077622000253310ustar00rootroot00000000000000#include "winappprofiletimerdialog.h" #include "ui_winappprofiletimerdialog.h" WinAppProfileTimerDialog::WinAppProfileTimerDialog(QWidget *parent) : QDialog(parent) , ui(new Ui::WinAppProfileTimerDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); connect(&appTimer, SIGNAL(timeout()), this, SLOT(accept())); connect(ui->capturePushButton, SIGNAL(clicked()), this, SLOT(startTimer())); connect(ui->cancelPushButton, SIGNAL(clicked()), this, SLOT(close())); } WinAppProfileTimerDialog::~WinAppProfileTimerDialog() { delete ui; } void WinAppProfileTimerDialog::startTimer() { appTimer.start(ui->intervalSpinBox->value() * 1000); this->setEnabled(false); } AntiMicroX-antimicrox-b300273/src/gui/winappprofiletimerdialog.h000077500000000000000000000010131471077622000247740ustar00rootroot00000000000000#ifndef WINAPPPROFILETIMERDIALOG_H #define WINAPPPROFILETIMERDIALOG_H #include #include namespace Ui { class WinAppProfileTimerDialog; } class WinAppProfileTimerDialog : public QDialog { Q_OBJECT public: explicit WinAppProfileTimerDialog(QWidget *parent = 0); ~WinAppProfileTimerDialog(); protected: QTimer appTimer; // slots: // void private: Ui::WinAppProfileTimerDialog *ui; private slots: void startTimer(); }; #endif // WINAPPPROFILETIMERDIALOG_H AntiMicroX-antimicrox-b300273/src/gui/winappprofiletimerdialog.ui000066400000000000000000000047651471077622000252000ustar00rootroot00000000000000 WinAppProfileTimerDialog 0 0 420 178 Capture Application true After pressing the "Capture Application" button, please select the application window that you want to have a profile associated with. The active application will be captured after the selected number of seconds. false true Timer: 1 60 Seconds Qt::Horizontal 40 20 Capture Application Cancel AntiMicroX-antimicrox-b300273/src/haptictriggermodeps5.h000066400000000000000000000017721471077622000232520ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once /** * @brief Enum of the supported haptic trigger effect for a PS5 controller. */ enum HapticTriggerModePs5 { HAPTIC_TRIGGER_NONE, HAPTIC_TRIGGER_CLICK, HAPTIC_TRIGGER_RIGID, HAPTIC_TRIGGER_RIGID_GRADIENT, HAPTIC_TRIGGER_VIBRATION }; AntiMicroX-antimicrox-b300273/src/haptictriggerps5.cpp000066400000000000000000000260311471077622000227330ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "haptictriggerps5.h" #include #pragma pack(push, 1) typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; constexpr u16 u16tole(u16 x) { #if __BYTE_ORDER == __LITTLE_ENDIAN return x; #elif __BYTE_ORDER == __BIG_ENDIAN return ((x << 8) & 0xFF00) | ((x >> 8) & 0x00FF); #else #error "Target machine has unknown endianness!" #endif } constexpr u32 u32tole(u32 x) { #if __BYTE_ORDER == __LITTLE_ENDIAN return x; #elif __BYTE_ORDER == __BIG_ENDIAN return ((x << 24) & 0xFF000000) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | ((x >> 24) & 0x000000FF); #else #error "Target machine has unknown endianness!" #endif } /** * @brief Effect message for no trigger effect. */ struct EffectNonePs5 { u8 _padding[10]; inline void build() { memset(_padding, 0, 10); } }; /** * @brief Effect message for a rigid trigger effect. */ struct EffectRigidPs5 { /// Defines if force feedback is active in the corresponding tenth of the trigger. /// Bitfield of 10 right aligned bits. u16 active_zones; /// Defines the force feedback strength in the corresponding tenth of the trigger. /// Bitfield of 30 right aligned bits. Every zone has three bits. u32 force_zones; u32 _padding; /** * @brief Builds a rigid effect message. * @param[in] strength Strength of the feedback force. Value between 0 and 7. */ inline void build(int strength) { active_zones = u16tole(0x03FF); force_zones = 0; for (int i = 0; i < 30; i += 3) force_zones |= strength << i; force_zones = u32tole(force_zones); _padding = 0; } /** * @brief Builds a rigid gradient effect message. * This effect starts with a strength of zero and slowly increases * its strength until it reaches its given maximum strength at the end. * @param[in] strength Strength of the feedback force at the end. * Value between 0 and 7. */ inline void build_gradient(int strength) { active_zones = u16tole(0x03FE); force_zones = 0; double grad = 0.0; for (int i = 3; i < 30; i += 3) { int x = static_cast((strength + 0.1) * grad); force_zones |= x << i; grad += 0.125; } force_zones = u32tole(force_zones); _padding = 0; } }; /** * @brief Effect message for a click trigger effect. */ struct EffectClickPs5 { /// Bitfield with two set bits which define the start and stop zone of the effect. /// The trigger is devided into 9 zones. u16 start_stop_zone; /// Strength of the feedback force. Value between 0 and 7. u8 force; u8 _padding[7]; /** * @brief Builds a click effect message. * @param[in] start Start point of the effect. Value between 2 and 7. * 2 is the middle of the trigger range, 7 the end. * This defines the position where the resistance starts. * @param[in] end End point of the effect. * Value between 2 and 8 which must be at least grater then start by two. * 2 is the middle of the trigger range, 8 the end. * This defines the position where the trigger "clicks". * @param[in] strength Strength of the feedback force. Value between 0 and 7. */ inline void build(int start, int end, int strength) { start = qBound(2, start, 6); end = qBound(start + 2, end, 8); start_stop_zone = u16tole((1 << start) | (1 << end)); force = strength; memset(_padding, 0, 7); } }; /** * @brief Effect message for a vibration trigger effect. */ struct EffectVibrationPs5 { /// Defines if force feedback is active in the corresponding tenth of the trigger. /// Bitfield of 10 right aligned bits. u16 active_zones; /// Defines the force feedback strength in the corresponding tenth of the trigger. /// Bitfield of 30 right aligned bits. Every zone has three bits. u32 amplitude_zones; u16 _padding1; /// Frequeny in Hz u8 frequency; u8 _padding2; /** * @brief Builds a vibration effect message. * @param[in] start Start point of the effect. Value between 0 and 10. * 0 is the beginning of the trigger range, 10 the end. * @param[in] end End point of the effect. * Value between 2 and 10 which must be at least grater then start by two. * @param[in] strength Strength of the feedback force. Value between 0 and 7. * @param[in] frequency Virbration frequency in Hz. Value between 1 and 255. */ inline void build(int start, int end, int strength, int freq) { active_zones = 0; amplitude_zones = 0; for (int i = start; i <= end; ++i) { active_zones |= (1 << i); amplitude_zones |= (strength << (3 * i)); } active_zones = u16tole(active_zones); amplitude_zones = u32tole(amplitude_zones); _padding1 = 0; frequency = freq; _padding2 = 0; } }; /** * @brief Effect message for a single trigger. */ struct TriggerEffectMsgPs5 { u8 mode; union { EffectNonePs5 none; EffectRigidPs5 rigid; EffectClickPs5 click; EffectVibrationPs5 vibration; }; }; /** * @brief Binary representation of a PS5 controller haptic feedback message. */ struct EffectMessagePs5 { u16 enable_bits = 0; u8 rumble_right = 0; u8 rumble_left = 0; u8 headphone_volume = 0; u8 speaker_volume = 255; u8 microphone_volume = 0; u8 audio_enable_bits = 0; u8 mic_light_mode = 0; u8 audio_mute_bits = 0; TriggerEffectMsgPs5 right_trigger_effect; TriggerEffectMsgPs5 left_trigger_effect; u8 _reserved1[6] = {0}; u8 led_flags = 0; u8 _reverved2[2] = {0}; u8 led_animation = 0; u8 led_brightness = 0; u8 pad_lights = 0; u8 led_red = 0; u8 led_green = 0; u8 led_bBlue = 0; }; #pragma pack(pop) HapticTriggerPs5::HapticTriggerPs5(QObject *parent, HapticTriggerModePs5 mode, int strength, int start, int end, int frequency) : QObject(parent) , m_mode(mode) , m_strength(strength) , m_start(start) , m_end(end) , m_frequency(frequency) { } /** * @brief Returns the current haptic feedback effect mode. */ HapticTriggerModePs5 HapticTriggerPs5::get_mode() const { return m_mode; } /** * @brief Changes the haptic feedback mode to the given type. * @param[in] mode New haptic feedback mode. * @returns True when the mode was changed, false otherwise. */ bool HapticTriggerPs5::set_effect_mode(HapticTriggerModePs5 mode) { bool changed = m_mode != mode; m_mode = mode; return changed; } /** * @brief Changes the haptic feedback effect. * @param[in] strength Strength of the feedback force between 0 and 255. * @param[in] start Start point of the effect. Value between 0 and 320. * @param[in] end End point of the effect. Value between 0 and 320. * @param[in] frequency Frequency of the effect in Hz. Value between 1 and 255. * @returns True when the effect was changed, false otherwise. */ bool HapticTriggerPs5::set_effect(int strength, int start, int end, int frequency) { strength = qBound(0, strength / 32, 7); start = qBound(0, start / 31, 8); end = qBound(0, end / 31, 10); frequency = qBound(1, frequency, 255); bool changed = m_strength != strength || m_start != start || m_end != end || m_frequency != frequency; m_strength = strength; m_start = start; m_end = end; m_frequency = frequency; return changed; } /** * @brief Creates an low level message from two HapticTriggerPs5 objects and * send them to the controller. * @param[in] controller Controller to which the message is send. * @param[in] left HapticTriggerPs5 effect for the left trigger. * @param[in] right HapticTriggerPs5 effect for the right trigger. */ void HapticTriggerPs5::send(SDL_GameController *controller, const HapticTriggerPs5 &left, const HapticTriggerPs5 &right) { #if SDL_VERSION_ATLEAST(2, 0, 16) EffectMessagePs5 message; message.enable_bits |= EFFECT_LEFT_EN | EFFECT_RIGHT_EN; left.to_message(message.left_trigger_effect); right.to_message(message.right_trigger_effect); SDL_GameControllerSendEffect(controller, &message, sizeof(EffectMessagePs5)); #endif } /** * @brief Low level function to write one HapticTriggerPs5 effect into a PS5 * controller message. * @param[in] effect Pointer to the triggers effect data position * in the effect message. */ void HapticTriggerPs5::to_message(TriggerEffectMsgPs5 &effect) const { switch (m_mode) { case HAPTIC_TRIGGER_NONE: effect.mode = EFFECT_MODE_NONE; effect.none.build(); return; case HAPTIC_TRIGGER_CLICK: effect.mode = EFFECT_MODE_CLICK; effect.click.build(m_start, m_end, m_strength); return; case HAPTIC_TRIGGER_RIGID: effect.mode = EFFECT_MODE_RIGID; effect.rigid.build(m_strength); return; case HAPTIC_TRIGGER_RIGID_GRADIENT: effect.mode = EFFECT_MODE_RIGID; effect.rigid.build_gradient(m_strength); return; case HAPTIC_TRIGGER_VIBRATION: effect.mode = EFFECT_MODE_VIBRATION; effect.vibration.build(m_start, m_end, m_strength, m_frequency); return; } } /** * @brief Converts a HapticTriggerModePs5 from string representation. */ HapticTriggerModePs5 HapticTriggerPs5::from_string(const QString &name) { HapticTriggerModePs5 mode = HAPTIC_TRIGGER_NONE; if (name == "None") { mode = HAPTIC_TRIGGER_NONE; } else if (name == "Click") { mode = HAPTIC_TRIGGER_CLICK; } else if (name == "Rigid") { mode = HAPTIC_TRIGGER_RIGID; } else if (name == "RigidGradient") { mode = HAPTIC_TRIGGER_RIGID_GRADIENT; } else if (name == "Vibration") { mode = HAPTIC_TRIGGER_VIBRATION; } return mode; } /** * @brief Returns string representation of a HapticTriggerModePs5 object. */ QString HapticTriggerPs5::to_string(HapticTriggerModePs5 mode) { switch (mode) { case HAPTIC_TRIGGER_NONE: return "None"; case HAPTIC_TRIGGER_CLICK: return "Click"; case HAPTIC_TRIGGER_RIGID: return "Rigid"; case HAPTIC_TRIGGER_RIGID_GRADIENT: return "RigidGradient"; case HAPTIC_TRIGGER_VIBRATION: return "Vibration"; } return "None"; } AntiMicroX-antimicrox-b300273/src/haptictriggerps5.h000066400000000000000000000051741471077622000224050ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include #include #include #include #include "haptictriggermodeps5.h" struct TriggerEffectMsgPs5; /** * @brief Represents a single haptic trigger effect on a PS5 controller. * See https://gist.github.com/Nielk1/6d54cc2c00d2201ccb8c2720ad7538db * and https://github.com/Electronicks/JoyShockMapper/blob/master/JoyShockMapper/src/SDL2Wrapper.cpp */ class HapticTriggerPs5 : QObject { public: explicit HapticTriggerPs5(QObject *parent, HapticTriggerModePs5 mode = HAPTIC_TRIGGER_NONE, int strength = 0, int start = 0, int end = 0, int frequency = 0); HapticTriggerModePs5 get_mode() const; bool set_effect_mode(HapticTriggerModePs5 mode); bool set_effect(int strength, int start, int end, int frequency = 0); static void send(SDL_GameController *controller, const HapticTriggerPs5 &left, const HapticTriggerPs5 &right); static HapticTriggerModePs5 from_string(const QString &mode); static QString to_string(HapticTriggerModePs5 mode); private: enum { EFFECT_LEFT_EN = 0x04, EFFECT_RIGHT_EN = 0x08, LEGACY_RUMBLE_LEFT_EN = 0x0001, LEGACY_RUMBLE_RIGHT_EN = 0x0002, MICROPHONE_LIGHT_EN = 0x0100, MICROPHONE_LIGHT_OFF = 0x00, MICROPHONE_LIGHT_SOLID = 0x01, MICROPHONE_LIGHT_PULSE = 0x02 }; /** * @brief Enum of the supported low level haptic trigger effect modes of * the PS5 controller. * See https://gist.github.com/Nielk1/6d54cc2c00d2201ccb8c2720ad7538db */ enum { EFFECT_MODE_NONE = 0x05, EFFECT_MODE_CLICK = 0x25, EFFECT_MODE_RIGID = 0x21, EFFECT_MODE_VIBRATION = 0x26 }; HapticTriggerModePs5 m_mode; int m_strength; int m_start; int m_end; int m_frequency; void to_message(TriggerEffectMsgPs5 &effect) const; }; AntiMicroX-antimicrox-b300273/src/images/000077500000000000000000000000001471077622000202065ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/images/48-apps-antimicrox_trayicon.png000066400000000000000000000100371471077622000261740ustar00rootroot00000000000000PNG  IHDR00WmzTXtRaw profile type exifxu 0DC7p|ii%q:Z:UIfH44xKx`0 $uޘ^s'6|VIޛ- V iTXtXML:com.adobe.xmp BsBIT|dOIDAThՙmUw\5C_720+í 4IJPA?i`If, I[DnV.Kwmumgwv90sys9) E9'V #8Ng8˝e$-X W'Uj֑'t`fC# /wD\W A碖<~.ME%H5cɯix\k%?H+#v%$GCr ǁO5lݻ@ߘu9zF6Pg'A[w[M ì+:Ċ8Sb`%P0ğbh R]S."z,)@)$ Lw.ZScs=ƣ>85!pRp9m40#} L :ۀIƘ0 V`G OvÀ>1:\$8]\ͭEE`uo ZDUh{ &Z8Ͱf0Ƞ|xJ ~9I"LȌ$H~CmpCh*Эa-x,Pz/4`r3?@]֩;"/Mpэ~ NkG pk9v"˱',߱WsqujKCLv01>#SЙ4'CR`t Vğ9å42ߠ5 O*m.T[$qǀ+Xe դ[L fңD/+CM~ s ;G%Ƚ*Ql_I~qW,/Ր)#"m2ιhs1sE[{)ȫbeoHXY6,foέД(늘 <\6{4Ie]HPg_G'[I=A\;CVt Qʛ76@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rz@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rzbLMc\i/lG4E=WnCxIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/application_exit.png000066400000000000000000000011631471077622000257110ustar00rootroot00000000000000PNG  IHDRaiCCPICC profile(}=HPOS";8DNDE EjVL^MGbYWWAqrtRtK -bxsx>@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rzhIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/archive_insert.png000066400000000000000000000006611471077622000253640ustar00rootroot00000000000000PNG  IHDRasRGBbKGD pHYs B(xtIME+6Sw1IDATxڕJ@vZ( >VY iD-bY]PILpYB>8~sf`Of xd/oH a4aB(bq]"0MxT%zb1J XXZV+4r"S;Q A2m\_ $V[ ]o|t}l_n"#B `vW_c |'6^!:]'S~~<Fڙ\+mRN$eCgv*r2K IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/battery-empty.png000066400000000000000000000010161471077622000251600ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATx͓K@Ǔk~aΤ6Cmn-'t-NB._(]\ :C؂P55ib 4ܻww{BR8Njzu ^(b ýl66ͷeeZ>$x<.V*}4/ˇkpvT.w,OSDKa%Nh4zlw$=Ax`Vxd2Eq2 Rb7XcA!wp"R^j 2AExy^Rr1 c: )F@d2cxs;c,_G1$d?~ <_Ȝe5odYVA(A?ΥaIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/battery-full.png000066400000000000000000000011411471077622000247630ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATxڍkaǿw^L1h(\Lq␿@YcA1 B6ilm.ܝ|)Br_|y3LrY(28uiј;^_VSUUs|߇a75Msko\ȲT*D%/Żii6 #L'3Eзst0xT*|؁ ?0 O11\R'eٰnj~td}?"y1T>%׻11戝 xp,Yyj߶ {v{o" ϸ*Y?!#p Pb yV*^_lvk-olDX$_.p!&=p]H#*$NAA v3BVbroj0@gzFPt BWIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/battery-good-charging.png000066400000000000000000000015561471077622000265430ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATx}]HSaǟn윳tVk4],#%.D(),.J(u!]uUMQ]$Uf>D8m^/עy}| 4|UUkvv6+`|$d~XŎK2922M"ȲmjjBwtt$PPBe~so%1IjkkXLommm+:6}cF&)Soo`~@BAH;Sߩ@pIRa< }<râ( f`֨W;4MEIjTAG&<>`S # ?sY(-m/C}n - Т!jT櫓.)S\s[*8}WX0 6 10 iUKgq},@g̃@mC38<8.I7PKMK۞i mLh)cH>a R !Y \ʉy-m&ezC7'`R9#x"TUe* }7K#g,#\}`THx\U/,xLCb[h QVJ"ѪCb?X5IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/battery-good.png000066400000000000000000000011331471077622000247520ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATxڍka^;6-T/pEh薥AtklRd(%.vʖA' %СR!J Q\PH>~y ˨T*ۅB!mY֢^nK o4;jՓeg.u>TUծjp א$}\X,ƗJǺt:n?VHQ6͆}0tn$ ǚFS(:45@na9^3h4jRK yKA08<9>5MxDTj]2  B`p3T8{b&dIor8=LS >&g09o l&"+H!2l \ ^8 Q !2Ɨ77O" 5CFz\/Nhl1IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/battery-low.png000066400000000000000000000010551471077622000246260ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATxڵSAKA]U4 ԋ7n^AEv桋O0ς'A")-R"M]7ݾC؂ۡy}3 e2C.L&Y'RiV2T*BAy)#UUQX JX|6 ql^/NWEQ<^ijz*T*0 ڽ^#m=7V\>w8 _6L164M:ȡPZB f`27Z50ǿ3q{oc1cc>E!؞0O 00v6CGRhD䏏2=7R})bnܶI.$su i9 E!,"sMx.xJjkD%wr[Eauߡ?<#\IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/calibration.png000066400000000000000000000013241471077622000246430ustar00rootroot00000000000000PNG  IHDRaiCCPICC profile(}=HPOS";8DNDE EjVL^MGbYWWAqrtRtK -bxsx>@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rz-x+?4*hW J= ZNylIWm=Zc_nh#s BYsT>LtX>i<[KK;a-T&,X|YA@mIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/dialog_cancel.png000066400000000000000000000015201471077622000251160ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<IDATxڥMHqƟ|:3~jiA u D vB'!(I:DI*iV~E&+NL u鹼&=f ] +\[;wm M싗A^ߖXgc_촃wA ay`P-in>UfCYi޾!X.CQ1&TU8XAƆo 1-)'++>_6Sڝ&EY햤,a< G|mfǀR~)Z@ln131e䪱k[ZDI OOPЄ8m?. [y m+Ʀg-Cnēb0 kAAGMeq  at5h8,466!2 &n'`sr-Ag#2Y !j?$WVpKefvXTUU !ѯ qDJH~#/S̅7HbjSVO7qr$3l4"6@#Xq hK=E}KoocA&8B阋ᚚUNs VIQIK)J1{"؊].F 4IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/dialog_close.png000066400000000000000000000014551471077622000250050ustar00rootroot00000000000000PNG  IHDRabKGD pHYs B(xtIME IDATxe[hήlGjc9-.EXJ22ɱ( ||H  XZLnvss m~}DC}1qj 7ZwMc12l.w~`K߷n߯ʊ+gθ6223Gx\lK&>X..TJKK%=믱%Oj zYanJG"8$8bMy椚mu:f.37#;;{-MNHK{4GtԷόZҾi[٧ic]Ⴋ5LO),WD\qO5AZ JAtW?̪j̊R*ZuUJK,Sz|@·;zUj&RC 1 9&BVsO30u.~uTm2Cfw))X8ZE&>K%W?v#jSvv@3yw)n)buYWH_d%@oЄe.|QQ`[~1|Ɋt]Q"Qd?8ɛ 6 @z#̔Y@%Z[QIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/dialog_ok.png000066400000000000000000000011311471077622000243000ustar00rootroot00000000000000PNG  IHDR(-SsBITO pHYs:tEXtSoftwarewww.inkscape.org<PLTE;7 5 9 #5>777 <;:: : 9 ; : ?"B!C"? = ; : 7 %K7Y'M1U2M5V5Z5\3Z0W4V9_5S1F0@1>4?/Mv*DS,Hi-F]3LW5LZ6R^;ToD_yD`MjzOjPmQkRoTpUqVpZv[v[w]z_|`}b}b~bbc{defgghiioptt}~ȫm-tRNS !.38G2sC2] `IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/document_close.png000066400000000000000000000012461471077622000253620ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs:tEXtSoftwarewww.inkscape.org<#IDATxukAJ~R1UIsAx[[<޼+*BVE%л? H5X"BnwV6yy2!c YG t`+?]m!* n5 c4Y8ۻ872T R^+J{}߇>*NNB!ΪB9ߑʸTZ[Wxs:.*Riv \OSҴg `lBN$<#+%T0cI6l[aH⑰eYh4rDR^'\tJAgj#C۶ ݵ(< pg$,-O_أxIRccQIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/document_open.png000066400000000000000000000014201471077622000252100ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitleFolders!T`AtEXtAuthorLapo Calamandreiߑ*)tEXtDescriptionBased of Jakub Steiner designsIDAT8KQ7:%$6bm$& ZԲۢ-AVeѦM!)*lѢRK%xfs}[O-)yQ.""f疘nXjMLbQ g~ebn9 0#_z! 0A@D6jiNx IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/document_open_folder.png000066400000000000000000000012231471077622000265440ustar00rootroot00000000000000PNG  IHDRasRGBbKGD pHYs B(xtIME)frIDAT8ˍKQ}]mm\"4V.o"EFEAIi{=g{Z)D}=}9=d)If{1( 6<7u_dvs_̠aEhǂD "Is݋㶳ӢMY`8=:ĥ )(ATeqi M6)1|P@D>0v8EO{{ng1ʻ*(ֶP]Fݢj9o(Ah,e*.^)"/|Z_eh?ZHkOL\ռ1B=a V>-fnߺAhP3>|\pgr lɣ)+f dy>Ƞ"ZAaEf*u[-P~(B>ЎCĎ8p6u4X 9!m.`n"wapHШ޽>@gcat2ΝlL )"UcR7dž0,1IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/document_revert.png000066400000000000000000000016641471077622000255700ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitlePaper SheetstEXtAuthorLapo Calamandreiߑ*'tEXtDescriptionwith a HUGE help from JakubTIDAT8mKhTI[V1|I FDžA42>p .m  d bP 1 3A("jۤ_tkֽU.EWV !Nk-XO n۸~-~TIkNXҕ-%=ϫTZƇ Ldػ7 $Y6Z>{: 5AaAƠ`r)%,_)2}@|g6&ChB._DWW GKsY91@ZhƂXCJjQR$US[#Rk0@ ň(JS3N$^R3*X g迻|2J(i Rh-m4l#{WbVDkPCA"uol?{gc\8̫kI 5wH) w~?z܆ H_3^U@)dbx 5x!ɇv<(u}]GTLMd 6z9p .m  d bP 1 3A("jۤ_tkֽU.EWV !Nk-XO n۸~-~TIkNXҕ-%=ϫTZƇ Ldػ7 $Y6Z>{: 5AaAƠ`r)%,_)2}@|g6&ChB._DWW GKsY91@ZhƂXCJjQR$US[#Rk0@ ň(JS3N$^R3*X g迻|2J(i Rh-m4l#{WbVDkPCA"uol?{gc\8̫kI 5wH) w~?z܆ H_3^U@)dbx 5x!ɇv<(u}]GTLMd 6z9cdO9=zNm ADx}#""_;YmK&AI"fMdvZ~6ϘYl5kT]H@)iXO>|4r}bz h4m><0992i8N)W0M ӴF044Lr%8_6̄IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/document_save_as.png000066400000000000000000000014051471077622000256730ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitleFile ManagerNstEXtAuthorLapo Calamandreiߑ*tEXtCreation Time2009-11-22&IDAT8KTQg9FIk%0( A1hQ-V-"uQ E6BjEB?ʦd&gDg=-A<#ZJuUlMY%tC.zdpΦ6JN!rwW^3}׺7ꆴK+ڢJ+nH[膼 *7F>=ݖ(\nH5ا+ݐj>Z'ھ qg - %p:^?.ujyZu :r!LpxR(m~7wͦ-fak?׷{O?[OsI+}:_I?YaAC  p(ėQRTXP|VKEΤf~ԫ_n06>Ff!|d"Ci{t_ j>h}fy1CL}D|b#OfCQ$QNNi=!#KKm"_,t}>Ú`f p U+Z<H!~ UP׫ef[9)) TJLj_vfz$O;gKKUJ=]c 2k #soEc+0$ L_oD)Sn,Ϳ``eqV& Ew#9)mHL$cllu"%3I@ MBdc#OPTr:d)-K-L誄HTۼo|xIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/edit_clear_list.png000066400000000000000000000012351471077622000255030ustar00rootroot00000000000000PNG  IHDRasRGBbKGD pHYs B(xtIME9eIDAT8˝KTQ?f4 b1,`hQ2V`̠]-jT(mM3HB,f,̼wZD/r/|Ͻt:q ;n լ! `* oe=bcZ_'TcKJg5RZkHXP@L$I`{ ƀ7e". ACZ٣cV׵Iȱ ~_+*.&ҊXXcvhq|i63jkܞ.>cq})<×'9/_&3c{ƿ-L ЦS+KbLP6ab,nw0(=K6ʣkٚ__1@ٕa1ɕ 7`* lj` _e/+5֦#Z^]RTU1}ѬswݮC w2z(l1'EO<ۑP(x;O'뾞ijjv-m׳G_wy ޞi_ָIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/edit_delete.png000066400000000000000000000020071471077622000246220ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitleAccessibility Preferences-=tEXtAuthorAndreas Nilsson+tEXtSourcehttp://www.andreasn.sezIDAT8eO\ew>/2%c`J@Lw5$ t4´XH غ M[XV2m| mHe(ISf`:}`%>s6\׵Ua8,"Ȓ eoysq.7Ƣۗ}ޥTa$Շ{W 6{{gOPEmm0miLh}y/[P|\y>cPU ۷؛CۺZ;YLTwp^!va3;?F[&1?ln;btӞ{R!v82kkU"| Ϟ:9xcpbP L^#_E8N O"zZ *8,^@U4 jR\) "RN:Y֋Enܼ\YAAl.<V v4NMׇL bOҬVU"i$><42S? E}6Kcvmo|&֎UeјnJ:?#~g= ]]e]%*֚A*cu$:o 4~$NsH4Ͽl, 7&c̏0a\#HWMCA:}4eX05eIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/edit_table_delete_row.png000066400000000000000000000015371471077622000266670ustar00rootroot00000000000000PNG  IHDR(-SsRGB pHYs B(xtIME$*PLTE <<<CC;;;;;;;;;유z{;;;슋߷rr;;;򎏶脄݃把喖tt;;;<<<~jjdey{_TtRNS@@@@@@@Gkkkkkkkksss||VbKGD:N IDAT]; PDs_n *Z*J0ܝB D$>5f`vxSVc? e-n?BOh -mܡCLtI& N)m單d2"r#ڽ0ų~AJWrh;Q%P/u*/ Ru8c.IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/edit_table_insert_row_below.png000066400000000000000000000015241471077622000301150ustar00rootroot00000000000000PNG  IHDRasRGBbKGD pHYs B(xtIME  ,D_XIDAT8˥]efk,Oud! $!:P̃)6Z0hj! <w]֠X[p޻5Ϻ↛I%T̟oHRqٳPj_iǁjop8& ]h?ZJٰ̍}å]==vF8IJsSE{=ϝwdT/⍂ăPұmk֣5x-tnx%6mk-=:uR'IÁ?Vk3*̿! b )l()R %Iߌ~/-#s+I,Wк=X9n ĄA}JCٮ\06&/r)Kk ;])yhSȰ"upҝD"~$32kLvtO)WԨz >uBUZ 5+[){FPBrYh%F|> 1Teɹ`_'(&IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/games_config_custom.png000066400000000000000000000021301471077622000263630ustar00rootroot00000000000000PNG  IHDRa pHYs oybKGDIDATU}PWxt]t]rNˍ "/HкRL!`-ŋ!y_E_**-?a1m֨4Vljb*tRzZ2aCZj9)ҔmI Riqq&>c4ł I$ +B8gW䮀JE%RSy ʨEZ欵}̃9E-fn.--QscJ,S^.Xuu6l'7NL3E%oGGGd4֔L&lh:^ʼ@-0jdϜ7v޳5>>A-..Ȉhb|M-- ܁ecJan9Y\Q |DUxl!햟ڂȮa6XJ\.8'ƀc0hP?_ ۂiRf8>XQQ\?hcuӃ3a'4p qZBd(`4y2k*/Э-zvzL<^ršZ |ʈA"^ϒX,^154>LnY՘s~kn>Ѓ`Cvzs5>UjjjfZ_uke*v9ޛi gP QΙI'oH%H111ɖaRTQv]w)8T!k0G wZZZ˲5[ׯ6яǠ#^a}CBBB!xႬ,˲ /$$$pcDyp۹ D2 #Q<O R)o""zTXtSoftwarex+//.NN,H/J6XS\IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/games_config_options.png000066400000000000000000000020551471077622000265520ustar00rootroot00000000000000PNG  IHDRa pHYs oybKGDIDATxumlSUǟsϹ}oұŷƲF$`D9~`(n1LpGsTc_ T]Z6M:5F6&aڷ޾{=4K'wlyl3H zһ=^ӅSR܅ӟMu`a{5e9׋QxEjP(FUUvJ KSp:/\! "<L44l8$J(0A\3O <-lΎd15>ozهIQ՟{H.WKK70fpD^*QKk`y,&z\U?ghߊyXSUj +UޣnB7NgyCfѴC`/̈37ћ7je2\:.P\[vwDBP1åe++1z 5wo) R<1ާ֨1A _A dR`0GNquWDHJ²,1#TXTܳ1vVVV~o\/ GK& ={^{mFS}сc*A(Fп3LKĴ&%|>}EE߾ zRC BtߋtV-NZ97tr"zTXtSoftwarex+//.NN,H/J6XS\IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/github_page.png000066400000000000000000000014431471077622000246340ustar00rootroot00000000000000PNG  IHDRaiCCPICC profile(}=HPOS";8DNDE EjVL^MGbYWWAqrtRtK -bxsx>@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rz@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rz ͺiL y]|t>W=._v<0xL*L<*0+5/qZ%]N+?̒vuԖq<V߄dh8IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/join_slots.png000066400000000000000000000031551471077622000245430ustar00rootroot00000000000000PNG  IHDRauzTXtRaw profile type exifx[* Y, `9K,~$IN!BH>A\lC0^4O1v|} C֏7 \\|r/7qX 1ABΫf(uRP^)PdYgs+,U#9;qw3B\ػhHhot|>|Λ}er ɟ)q~.Sk콭o}@FVQ\3az74-l -l W[V(J7RNm BX3vSr2uV.efXhM_ϕc%OiL3"qQcOh_چJe9]Vе'-DFf)oA0@rB2+(#rv s2 |ceC `=X G}D eqE$J4$|qeuU4jԤ95ƘbN@I!i)d8ʰ!Yxq_d .qIK.(⋔PĒJ\]1QCki8)oB[jֺK]{F[;A6j歅ȋ\D v.|7p ֕9DvzB>?{?* ēiCCPICC profilex}=H@_?E*"vqPĊVBЪɥB$Qp-8XupqU?@]%1ݽ;_/3 fdBV+ϊb >y?G7gnXSy8JB|Nrlvz}ݬnl_.uK6N%!Κw[Iv3̩~^ |Ti;XT2W:v4lS9ıS:ܲIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/key_checker.png000066400000000000000000000014071471077622000246320ustar00rootroot00000000000000PNG  IHDRaiCCPICC profile(}=HPOS";8DNDE EjVL^MGbYWWAqrtRtK -bxsx>@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rz@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rz|?XD#-B"IzM; ?/^dsa6~~9_uR C<7Y̡h+6XM%)m] mf K^g 6]C6eIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/settings.png000066400000000000000000000013131471077622000242120ustar00rootroot00000000000000PNG  IHDRaiCCPICC profile(}=HPOS";8DNDE EjVL^MGbYWWAqrtRtK -bxsx>@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rz5K$$&'|czo"M nIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/sliders.png000066400000000000000000000013261471077622000240230ustar00rootroot00000000000000PNG  IHDRaiCCPICC profile(}=HPOSKE**vqP,8jP! :GhҐ8 .κ: x_Rh8{B4c tL'b6"_@}EHf1+I)=uSyߟխ-Df6:Ԧmp'tAG+q.,̨IGb+mJF.Ш94N3p:0IzŎm⺥){0dȦJAZB7[k՛[@f"e}n4rkY9bKGDyX pHYs B(xtIMEVIDAT8ӱNBAУтJCac!ƎJcbG/PVb ΞR-$@3lS Lvٹ3h9(7U @funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rz-{C<$%901?aw(B3 $|iq'~m&ؙ7HY M axd+kcK&py 9hQ 98bKy|dl;IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/text_field.png000066400000000000000000000005171471077622000245060ustar00rootroot00000000000000PNG  IHDR(-SsBITO pHYs:tEXtSoftwarewww.inkscape.org<HPLTE fz g h h/UwgihihghLtRNS224Gxxxxxyz{|}~ZWIDATY@*mM%.Ѳ9W *zGy=:G u#mi}Q D%8ݖ:t{, IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/view_fullscreen.png000066400000000000000000000010571471077622000255530ustar00rootroot00000000000000PNG  IHDR(-SsBITO pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitleOptical Drive>g PLTEU@@33MF PGQ"JKG!LILH"J"L L I"L!J#L"J#M#M#N J%O!K J#M!K$N!K!K#N$N%O(Q"L"L#M K!K J#M Jüaxy2tRNS &)+/19IJL[hvy|| oIDATu`G3l[UJ}ВDD !жi0,Q,8Ju<|h!;Y#wqNW<Ԩo7R\<:C/!I<}B1O|RΏ6 BreF7ZH{IENDB`AntiMicroX-antimicrox-b300273/src/images/actions/view_refresh.png000066400000000000000000000013371471077622000250500ustar00rootroot00000000000000PNG  IHDRaiCCPICC profile(}=HPOS";8DNDE EjVL^MGbYWWAqrtRtK -bxsx>@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rz@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rz).200(1 g PdB; p3)6$`?`.@꒻pKچeY A<aBٕIENDB`AntiMicroX-antimicrox-b300273/src/images/actions/wiki.png000066400000000000000000000015641471077622000233250ustar00rootroot00000000000000PNG  IHDRaiCCPICC profile(}=HPOS";8DNDE EjVL^MGbYWWAqrtRtK -bxsx>@funD\dW+2$) nzԜŀH< & ޴ VUs1.Hu71өyXhcYԈSXY+WY᜾uZCH`K BA%a#FN}_"B9PZ /):_c|;N>Wz_3ZZ.[\Olʮ%}S׼5qiV-PϻoOs~?rzI9c{QE\ 71fq.كVULe#eiv`gLK󽄟W3YTSӑ7~ '8 h)p/"kx=[q_.~8 y??U]zU71IENDB`AntiMicroX-antimicrox-b300273/src/images/antimicrox.ico000066400000000000000000010200761471077622000230650ustar00rootroot00000000000000 ( ( ,"bK9!\F(nS0{^6f:{^5nS0YD'K9 * _ */#u7*P="bJ)eM*gN+eM*aI)R>#8*0$w /8+wgO-ϑo?p@p@p@p@p@p@p@p@p@p@p@n?eL,5(q1&YC%fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ZD%3& #E5h : 7l>p@p@pU0fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ W`J)p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@vZ3vZ3ޓp@p@p@f:fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+Q<";p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Q>#P<#p@p@p@p@p@nS.fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ RT@$p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@']&\p@p@p@p@p@p@c8fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+E4l=p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@f: " "d:p@p@p@p@p@p@o?jP,fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ +?0p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@hO-gN,Ɠp@p@p@p@p@p@p@p@z]4fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+8*vZ3p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@;-:,p@p@p@p@p@p@p@p@p@k=fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+aI( ?p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@m> > p@p@p@p@p@p@p@p@p@p@pU/fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ YM:!p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@x\4x[4p@p@p@p@p@p@p@p@p@p@p@`7fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+?/b8p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@VA%T@$p@p@p@p@p@p@p@p@p@p@p@p@l=fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+dK*>p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@*c)bp@p@p@p@p@p@p@p@p@p@p@p@p@p@pT/fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ YE4p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@f: & &f:p@p@p@p@p@p@p@p@p@p@p@p@p@p@|^5fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+7)jQ.ӓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@jQ.jQ.˓p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@h;fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+\E'o?p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@?0>/p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o?hO,fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+$ Pp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@n? D An?p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@rV1fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+(jG6p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@{]5{]5p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@|^5fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+7)_H)Óp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@YD&XC&p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@f:fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+T?#d8p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@,"i,!hp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@m=fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fL*p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@h; * *h;p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@iO,fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ / Gp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nT0mS/ϓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@qU0fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+$d7)np@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@B2B3p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@wZ3fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+3&|J8 p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o? I Fn?p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@|^5fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+4'P="p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@}_6}_6p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@b8fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+A1\F(p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@]G(\F(p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@f:fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+S?#jQ.Փp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@0$p/$np@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@h;fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+_H(tX2p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@j< / -ifM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM*j=p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@G6F5p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@m>fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+gM+l>p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o? N Lo?p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@m>fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+jfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fL+d8p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@?0?/p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@l=fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+tX2p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@.#n-"lp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@j#p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@e9fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+P="P=#p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@wZ4$V#Tw[4p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@b7fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+B2H7p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@eM,$V%WeM,ȓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@|^5fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+4'-#dp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@c8Q>#(] . .(]O<#~_6p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@vZ2fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+1%x Cp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@f:z]5x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4x\4z]5f:p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@oT/fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+!`p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@hO,fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+,|^6p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@l=fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+dK*XC&p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@e9fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+M: E5p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@{]5fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+5( Jp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@rV0fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+%f k=p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o?gN+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+aJ*Ɠp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@g:fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+VA$B2p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@{]5fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+6( 3p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@mS.fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ MtX3ߓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@k=fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+`H(G6p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nGmSk\k]lUnJp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nIlTk\k]lTnHp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@~_6fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+:, 8p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@jad]YWWWWWWX]bijoCp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@oBigc]YWWWWWWY]cjdoAp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nS/fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ SqV1ۓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nMcZWWWWWWWWWWWWWWXalWp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@lTbYWWWWWWWWWWWWWWYbmOp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@jeM,ʓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@oF`WWWWWWWWWWWWWWWWWWWWWWWWWW\mPp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@mM^WWWWWWWWWWWWWWWWWWWWWWWWWW_nIp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@g;fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+XB%5(op@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nL\WWWWWWWWWWWWWWWWWWWWWWWWWWWWYk]p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@lWZWWWWWWWWWWWWWWWWWWWWWWWWWWWW[mRp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@x[3fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+1%l>p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@mOZWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXjbp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@k[YWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWYlTp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o?iO,fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ (ZE'p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nI[WWWWWWWWWWW[wãɬɭŦ~^WWWWWWWWWWWYlXp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@mSYWWWWWWWWWWW]|ĥɭɭäy[WWWWWWWWWWWZmMp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@e9fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+N; (\p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@^WWWWWWWWWWlĥʮ{WWWWWWWWWWZnIp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@oE[WWWWWWWWWWtȫƨqWWWWWWWWWW]oBp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@uX2fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+,!s f:p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@dWWWWWWWWWbƨ϶lWWWWWWWWW_p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@`WWWWWWWWWi̲ȬeWWWWWWWWWbp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@n?gN+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+eL+R>$p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@lVWWWWWWWWWyWWWWWWWWWhqp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@ihWWWWWWWWW}WWWWWWWWWk]p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@b8fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+D3 Jp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@^WWWWWWWWWWWWWWWWYoEp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@oB[WWWWWWWWWWWWWWWW\p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@qV0fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+%e~_6p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@jdWWWWWWWWWWWWWWWWep@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@fzWWWWWWWWWWWWWWWWimp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@l=fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+dK* I7 p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@^WWWWWWWk}WWWWWWWYoBp@p@p@p@p@p@p@p@p@p@p@p@p@p@o@ZWWWWWWWwoWWWWWWW]p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@~`6fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+<. 8p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@mPWWWWWWWWѹ_WWWWWWWhmp@p@p@p@p@p@p@p@p@p@p@p@p@p@jeWWWWWWW\վYWWWWWWWlXp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nS/fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ SqV1ۓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@dWWWWWWWWWWWWWW_p@p@p@p@p@p@p@p@p@p@p@p@p@p@aWWWWWWWWWWWWWWcp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@jeM,ʓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@k_WWWWWWW̱WWWWWWWf}p@p@p@p@p@p@p@p@p@p@p@p@guWWWWWWW϶WWWWWWWigp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@g;fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+XB%4(np@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@gwWWWWWWWWWWWWWWbp@p@p@p@p@p@p@p@p@p@p@p@cWWWWWWWԾWWWWWWWfp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@x[3fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+1%l>p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@dWWWWWWWfWWWWWW_p@p@p@p@p@p@p@p@p@p@p@p@`WWWWWW`XWWWWWWcp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o?iO,fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ (ZE'p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@cWWWWWWYqWWWWWW^p@p@p@p@p@p@p@p@p@p@p@p@_WWWWWWm`WWWWWWap@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@e9fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+N;!(\p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@bWWWWWW^vWWWWWW]p@p@p@p@p@p@p@p@p@p@p@p@^WWWWWWreWWWWWW`p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@uX2fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+,!s f:p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@cWWWWWWYqWWWWWW^p@p@p@p@p@p@p@p@p@p@p@p@_WWWWWWl_WWWWWWbp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@n>gN+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+eL+R>$p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@dWWWWWWWdWWWWWW_p@p@p@p@p@p@p@p@p@p@p@p@aWWWWWW^XWWWWWWcp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@b8fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+D3 Jp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@guWWWWWWWWWWWWWWcp@p@p@p@p@p@p@p@p@p@p@p@dWWWWWWWӼWWWWWWWf}p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@qV0fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+%e}_6p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@k\WWWWWWWʮWWWWWWWf{p@p@p@p@p@p@p@p@p@p@p@p@hrWWWWWWWͳWWWWWWWjep@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@l=fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+dK* I7 p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@oCXWWWWWWrWWWWWWWk[p@p@p@p@p@p@p@p@p@p@p@p@mRWWWWWWWuWWWWWWWnHp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@~`6fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+<. 8p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@^WWWWWWW]WWWWWWYo@p@p@p@p@p@p@p@p@p@p@p@p@p@ZWWWWWWZWWWWWWW\p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nS/fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ SqV1ۓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@eWWWWWWWWWWWWWW`p@p@p@p@p@p@p@p@p@p@p@p@p@p@aWWWWWWWWWWWWWWdp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@jp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@mQXWWWWWWWWtWWWWWWWWWiip@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@jaWWWWWWWWWuWWWWWWWWWlWp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o?iO,fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ 'ZD'p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@fWWWWWWWWW^ŧȫeWWWWWWWWWap@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@bWWWWWWWWWd̲_WWWWWWWWWdp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@e9fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+N;!(\p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@_WWWWWWWWWWg£ŧnWWWWWWWWWW[oEp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@oC\WWWWWWWWWWnǫgWWWWWWWWWW^p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@tX2fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+,!s f:p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@oE]WWWWWWWWWWWWoǫȬävYWWWWWWWWWWWYmQp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@mMZWWWWWWWWWWWXt£ǫȫ¢qWWWWWWWWWWWW[nHp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@n>gN+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+eL+R>$p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nJ\WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWYlYp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@lTZWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW[mNp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@c8fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+D3 Jp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nH]WWWWWWWWWWWWWWWWWWWWWWWWWWWWZlUp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@mP[WWWWWWWWWWWWWWWWWWWWWWWWWWWW\nKp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@qV0fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+%e}_6p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@oBbWWWWWWWWWWWWWWWWWWWWWWWWWW^nKp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nG`WWWWWWWWWWWWWWWWWWWWWWWWWW`oEp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@l=fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+cK* I7p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@ijZWWWWWWWWWWWWWWWWWWWWWWXfp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@fxYWWWWWWWWWWWWWWWWWWWWWWYgpp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@~`6fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+<. 8p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@oEdYWWWWWWWWWWWWWWWWWWWanLp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nJbXWWWWWWWWWWWWWWWWWWXcoFp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nS/fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ SqV1ۓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@oFe]WWWWWWWWWWWWWWZcnMp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@nKd[WWWWWWWWWWWWWW[enHp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@jp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Xɳp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@sA`~|]q@o?iO,fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ 'ZD'p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@_ͷp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@xDvri;fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+M: (\p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@_ͷp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@qdfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+,!s f:p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@_ͷp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Srm#p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Xͷp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@k\fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+D3 Jp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Tͷp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@wkfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+$d}_6p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Tͷp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@xmfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+cK* I7p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Tͷp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@n_fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+<. 7p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Tͷp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@XwxBfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ RqV1ۓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Tͷp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@q@xmfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+^H(?0p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Uθp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@I}vk[2fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+6) %o?p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@sCdnnnnnnnnnn˹yyyyyyyyyxdp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@{Fk_iV0fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ =dL+ɓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@\vGp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@yDTYOiU0fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+WB%4(np@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@íp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@c}~krCp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@uCyEtCp@p@p@p@p@p@p@p@p@p@p@p@p@x[3fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+iN;mNKjN;fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+1%l>p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Uθp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@{O«ѼӿȲXp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@qAN\aaa[Lp@p@p@p@p@p@p@p@p@p@o?iO,fM+fM+fM+fM+fM+fM+fM+fM+fM-wQuUWWWUwQrfM-fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ 'ZD'p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@\Ѽp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@xӾqAp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@sBYaaaaaaaؑVq@p@p@p@p@p@p@p@p@e9fM+fM+fM+fM+fM+fM+fM+fM+gM2TWWWWWWWTgM1fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+M: (\p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@\Ѽp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@DzѾtEp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@ۓWaaaaaaaaa͌Rp@p@p@p@p@p@p@p@uX2fM+fM+fM+fM+fM+fM+fM+fM+SWWWWWWWWWSfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM++!r f:p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@\Ѽp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Įмp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@~Iaaaaaaaaaa`wEp@p@p@p@p@p@n>gN+fM+fM+fM+fM+fM+fM+fM+oOTWWWWWWWWWWWnOPfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+eL+Q>#p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@\Ѽp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@kp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@ԐUaaaaaaaaaaaƉPp@p@p@p@p@p@b8fM+fM+fM+fM+fM+fM+fM+fM+~SWWWWWWWWWWW}RfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+D3 Ip@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@\Ѽp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@qBθ|Op@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@[aaaaaaaaaaaؑVp@p@p@p@p@p@qV0fM+fM+fM+fM+fM+fM+fM+fM+TWWWWWWWWWWWTfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+$d}_6p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@\Ѽp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@sp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@[aaaaaaaaaaaڒWp@p@p@p@p@l=fM+fM+fM+fM+fM+fM+fM+fM+fM+UWWWWWWWWWWWTfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+cK* I7p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@\Ѽp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@пϺp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@ۓWaaaaaaaaaaǎRp@p@p@p@p@~`6fM+fM+fM+fM+fM+fM+fM+fM+fM+SWWWWWWWWWWWSfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+<. 7p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@\Ѽp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Up@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Laaaaaaaaaaa|Hp@p@p@p@p@nS/fM+fM+fM+fM+fM+fM+fM+fM+fM+tPeWWWWWWWWWWWrP`fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ RqU1ړp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@\Ѽp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@zLqp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@q@[aaaaaaaaaܔXp@p@p@p@p@jfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+6) %o?p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Zлp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Swp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@uCבV`aaa`ύSsBp@p@p@p@p@p@kQ-fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+iN;SVWWWVSiM9fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ =dL+ɓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@tEϻp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@sDgp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@uCJLJsBp@p@p@p@p@p@p@g:fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+iM:sPcwQqsPciM8fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+VA$4(np@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Ӿ\p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@ѾsDp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@x[3fM+fM+fW9fcIfV7fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+1%l>p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@eƲʷʷʷʷʷʷʷʷʷʸƯʷʷʷʷʷʷ˶˶˶˶Vp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@­ҿp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o?iQ/f}ffffffsfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ 'ZD'p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@\p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Sqp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@kBffffffffffP/fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+M: #Up@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@T̸p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@ɵĭp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@pfffffffffffM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+)m}_6p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@T̸p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@vH[p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@lfffffffffffffMfM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+cK) B2p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@T̸p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@Xmp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@vfffffffffffffM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+9+!l>p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@T̸p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@VҾhp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o?hfffffffffffffM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ 2M;!p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@T̸p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@tFî̸~Rp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@a7ffffffffffffffM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+C2 #l>p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@T̸p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@xKìȲ~Sp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o?kQ-ffffffffffffffM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ 7M;"p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@T̸p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@a7fM+fvffffffffffffwefM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+C3e:p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@T̸p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@m>iP,fM+fO.ffffffffffffM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+dL* '3&rp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@T̸p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@x[3fM+fM+fM+fcJffffffffff]@fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+1%nT/ӓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@~R˶p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@i;fM+fM+fM+fM+fM+f^BffffffffY;fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+WB%  1j=p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@rCʷp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o?mR.fM+fM+fM+fM+fM+fM+fM+f^Bfrffpf[>fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+ B3'vp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@~Tp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@y[3fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+4'`I)p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@hʸппппппппппоï}Qp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@f:fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+P<"vY3ݓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@jlR.fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+eL* ; Hjp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o?tX1fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+#q!PhpT0fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+dK* M (oU0ԓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@ivZ2fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+dL*)}ZD'p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@e9jP-fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+N;  /&YvY3ߓp@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@k=tX2fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+_H(%o2&pa8p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@m>z\4gM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+dK*3&7*uw[3p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@l=z\4hN,fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+aI)3'(]`I)Ño?p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@o?g:vY2fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+S?#-"x ;-{iQ-ґo?p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@i<{]5kQ-fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+\E'5( 8* _R?$sW2ߑo?p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@p@k=c8w[3kP-fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+fM+bJ)D30$x 4 D9+pK9 R?$bK+nT0vZ3b8h$3=uOݺB!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!b&; ?%g[Rs`,%T_ QE>-ˎ8OpAB&gBp&g\n+A3 0V:йEQ*1_>.?u^=76kE%5W h@'C/( EeiLQc(Rf|k_Lz|؈{PvZ[xIchG߹DƘ";2r FJJ! \TC`ZRf|ā?>fE @m/k@4+;&BΆ:*J ʹ47draGǞƏoq%M Z1xs\혽 TJs20Rf;_˩#oLv<^4(_0j_pέ~8x^*@1;ai S&GɎXhP:+5gLQ41!*4 )Tri!d#o}ضgL/eDA @c=+.̬U}ʎٸCar X1EC/>rOn˲!PaDY.\ϲ P4_Hv<aThe0G>ۓvDv8>xPw՗~uޒkF!!g%PfPALCa LJ|WdBjCDZo/Z-Vv,xUEv -`))G^XPXo+Խl=)x:Dn8?| |Jv4(p1-N^s]7!F  Y1k~KQJ,y?|pJv44:ȎE);%;Ed*9>Luezrec!ٔrdG١4S^xS>,;kcJϲ Q}piVsLJPJca >Û87hO P͖dBrȌS5sG`,9[v,(,J!G$>zYv8$fͿh-} 'eBF(2XImύ{Iv8t=͟yPS=B c 8* Ak#XZ'oM#BU+n@(!;B BLu`97[ɑiX$ֳ|խ{ʎ"S"-(;:BX׼k؛iX h_}? !D>G(hw`/2eu.#-ݲc!S>J58\!;E^^ٱBG5JY6p-jPJv,^F @ot=_v$򇢈nD^vNj2J4gй;eAqPZl578Nաm`M /1#H ^˲Ci(Z 2CVH[sogU %n#,?npLd84<΅'ī870yx %VbL_}C~";/ /Dzˎ^v}9]OGs7oBJTE-x{Ra\v,^Aj0}uū_d,~=WvT;@IcBhɾWkc Jf(5g 6o>ێOx[`̓?7!nFP.dP@Oʎ h BEW^ঋVIO|DCi'U샢%Zm0K-X ^~7.q+ `~*~M}R -͏Hk2#>F"\ X3tT 080nKrM>_ gA Yt/7ȎÌd &/:R-C U-I S5uM"V/n*}OzH7ɲt9oxˎh |p Cvf4wyvl9$b`l]kOw] OͫL1ywӣ3 7?/!NC8~֯O> |&Wh\]G$^pefFouȎBv>w>\kcGm2wP}e+>";`:) .߳Z!N1gw!p˅֝ T4е|:CFwS?B|({<~eȪ 7:ylW~]vnD )@8.;BH󉦺SnIv׬n@OvnC )_(z9b1G褶\g\ ;n(^/pڗu-ZudA~ z;ItbR'8>#x&2yɑ7p V wDі9lX܂ Z !f1,׃ rA/|gxBGCX׉ WVN=:;"S(:zS4  ScX5`X5 x5{Bp6{_*;mZ =ˎ3V/k/ìvslO{p˰(Dd qt$oic)Xj3x[9~K ^]7l4=,򣷣s5f ˎKNOQ5b)bՁsoʎ-(-lMqRu^ٝ;xRٹ whp9&\8ZZ/ݲpJi'^/[MS};B5wj,m?hm}<: pdecEa yi^DȘz R e[jl?WQu@J=xY(N0yZ]2בi{I /FG";C0 ?2 yȾ熯k/ȎCOz_I1R+.}g3-6CMY 2[ڷ-+V6NXgeAH-f WS7Zةw_帥 Gm9'0E %ڗɎCN)Ov̔*}.]Ip34mGxv[;',?wY60dj!Enu~f/\ujb}GF;}7x^L]EiڂxM$o %ˎ.y>\vs ~QW3?Ι?a_ʺcy0 _Ku.Z{2_䀹]th,D$hTL3\)nءt K`m{[`"k]\^Ӳc)>lq,#XZUuZomGـgETɖ3D?>>ÓfCt+0f0,yؾ5`,p_ |*M@`+r?=|IغЋT_`Ra\v,Nkuo7^ gwB9J~Y?/} g}Q 3Ջ)j"ʏ{nlZ,}s^}kc9ZȎiMt.ZsU qkbwÒyw]sY,i#A%%P.TO_O2 t8EiПx;1h5Z L]r8WoP Or0,58Kڹ~1xƈ?Dqxum#4ׄ`,ta.XxUBqiO1]v` ׫Prq`>{ir ePvNkGΓ>ߙK7W.ľ#1- #ʅ@b:\qL#ҋPlT_? zzq ACbqrJ`E#4paQF9Tj1rhGcpZS%Xrvg`8driF Ҥ&vlKy"<7$W#ZN';W Hߊm%p ;%*-MmZAyyxg5"ۘ>Kٱ8t,Zs'Â暍OV["$bp|'}oX%!ںIT-ѻv`GIɗ:naZ^up%$; '5r:wO3fg&Ș9w=Xd5_ Euc?ba`_ \P 6G(޶Iv Nj >ke)Wn)U MԊ54Z65x S6bDUPCP4{Bk60ԿXY!_Ql87ً/;4MԪX.;z> LfKQ4N 鴴/Em5c@jz>h=ReEs(;4G1 Vt!!L*up0f)ZYk,=&S|h$~nSwR)7T iern8)dMhbbTPszg̰mܾ (֏h7B-3mqB~,ŏ5oP q8)'7X`zm{[raLEվ.-mkz W8H_yItlHWWRX`ɝ?12՘f[Oִi9J=6~Jl- %:!PvvkMH>{X~L!LLqgnhlʲcM(c!y ԁz0D@qحZ}QK+tpxGF,z.G+ϮsN!I* M!t#ra*WD"r J|\T1)T0.bx2Ll“i۱@8P_,Xp*x?Zda'bqC?R1.6 Ŋapv7eW+fMu< _@~:Nqx'6tpK?Rss%0|ߩȋp! `dQ 9ljf*@; "kqag9K:eWWӸm W4Ooa8pLv+LzvJ)J;jb\*~MfxJdCCWɎ ;@R?gT "r_?vԈv?moNR9ZWJi ??Zl_42x2ct Ȑ/bhL~]9 crU[ˍ o`|Uir&*VF 51;6dIl' 0-j|Gc|*#_b!7Jˏ C/8CxWr|L^Jx @ht{1{醁/!hܪ%Э̊!L m1}:Q P%cپrvb !R{7~|u,`2cn* = !7O`^<1M t9XhJFp usFE7K;=|m\ _+޽[9c;R׾w7lrݬx@pϋbq/Y8 K#vTe`%E]~?*/(;3jc90%Sp/t㙭{dtg^1 bM~:x _wtԒc6 C#?T_P lcQW0viū>? ,a@ AW+r(,EpEne&YC%m+nZò8PЏ+)l<&Yc0wpxO&&3ytZ蒡\]Ɩ]l-!eW܏~0&jqq9?vaرg) bnM^+FOS0@Bcx QHCؖ3-=a١XCZv'~6&q*ފHлkJ/g^kQUzb]8BA?Eyw`.P,W0cס!<ƾ[o hT0*94Jޑ dѩ|h`(`:g`ǶvPTR?xUCiX7haplu[vJs@8JQ^@$,; aSs㼂o`,-;+4"|Kz~;kҩ200Ϟ!T;dx@03[9nٴ4r it]ǿ8n_VB܂) ɹZ|T !Pdc3oa|_ H !!c' aE/:Q-^0;S C:dS^u[v츄d1|ϏC#} مCo 5W~8܈17\,vXO}blR^ZBkY.؎MXbC{=y|*wzBϽWvlB00yhG*_eCtͥ 3i IDATQ:z>gW.u $~8 fbV)XEӺPt|@!sI-9c ?9䜨%kV! u#48ϰڈ;Sڻq>4]b:^sD iTW_đeG!=҉nٱP?k|Q=#܄c$&;#ocag C<Ɍ?Ɓ㎞23hRv )wՏ~uXrRhN7.X-(ruOmyf q-$ E 93Jpu]>XN @5wy

(;Xu`,it@t vHL C*0TaLc+}@Wz=Mg0C1 wTpV xŲc8&X!e,+ ,*3:!0ElgPI̮,- ,* :؊:jxr aga['* 0*TJ':qX{ o՗~%qV+]' aԺ%yE`cxgtL 32Đi!'FdpR7㘎;?ь)ԢG*+(y+^Qf갼$peV`l7V4"\]h8oa Mr+7xɬU}Vvzu>4%0Gwχ:Ɂ ?c9vXXU9g(Ln)Wdr2%@q ½[X΢.,TW7M9M Wg1`CA0h!/CApYN࿌jG>ܜGCwV SJsS$~s)>n%dА=k:D8qL, Ɉe%5]QK?nބlHjhh)Xj8NiגiXq8{to'p~A 6~k#I+1\Q.b]? J9܊hL)5g39' n;=:CI9٢5tq|lCqZW8Js\p'86fHuC8Np#u#',. |a#%.(|,f&|3|tc;T;U;ʎפxiʘ&VD4Wt+egCl }-riNຬiM!Z}OV"`8I`[;iu:"vCH.[A kwAiHQ@=Úة<)$=ǀ=ǁ{ 4Nv~Am@u/z[d`ǀ]C`Fþ$O nU# =C=6~`eO7uK8<Gaӭ?cN5g!q󻡾vJўm M*x%__qUs C,T3%eC0 !ۓd?mS0WGgS:ϽMvDS neQ뎫0{[1y @/wBYw8S0-eQ.Ia/ZBQ*9sFi4s}y/X.>=a/TxasK0P\EQ;JC,'pyBa,sawQ18:G;(Gǡ+W2LA<`>3!0bp]!:͞KWQVJȝ7G,VtP@{T;ge!=mnEӓns?X|FTy^1Tȝ;?: k$B_DvUN` `A7ػ(P֡@Ph*J:PX m, mºٝ !xۼݯ~Ef R+/62c (>2eT1E?Uu14|D+Vbc'"뒜@ٽ ঌC~\ ~F g IF׭Ьd2|G pjƢ@(%33] /ظPZ*e}FK <V\AS9q%0ÚPT?t;.:ł!xB:ZP7-U篂Xmk`e?90vFΝgfW`E+ r iLn?ܝ=eMǼ+}sA!C:5gi+:u De 0L\u -9>fQ?q\O]f [ O#/FقLnϸ?@ yE3!P;1xmdnTĘr 6:m bk>g \f 6RlK{:5AFhLk;cEvGt-DzN/-u]ւU@i !k\?uJ{LҼ@*r2# P1> r5 ƨ7b;Jm {/qn"W0w$JSBay-*1SqK\`]A v4̀_-<#֛W:ڀsu̾Hƹ$ջ׌̙'.YϚL'0~:Ӄ91㪬dh#Dܙm~gRYNbL:Bk*RלT+;I_ʚL*9`@3fs\`E+1Pzts-Ygtki*U%ۤtt<k -K}N|0 s|TL^X'1G9-A𫼟0y9fuT-;P}nfKow_I;&! @7weW$gK&Es'75ߕ"Vz*ɭLΐ9أc9wu6M+̫3uS+WZIŒ5%JsP2QN%+q\1E9tݚ,*a"P yeNUI^۰|9:;${nDNâf&Ι \9oRŀaQH_HXu~ ׬d6mY~场_<'8LMS\rUaD(ԿVeQYm2!Nwtsֿ-#MfFcNhl~i.fgXja_cn*ջO_QBp} EEepkن/9u>oZs͂0q1R.v<@iv{ݯ[q.c\#XIϬlRs)*,65Y@V=q$éԜW:q.>f֘z'Sy{oˊsO칑\ , Yd§4nN DZC .::/<yu -~Bydf;`sc3pI0+U:I?@"н?qL\3hs3u7cAu*l[Jwu%-y'6bWPe!=Owr!Yt=Lv?.&%~@h xKe;ueiɏs:G ;D݊6;hEmQ?6ЊuʽØʕLEA#@!7΢#njY\Lf|iHݽ7@mL@D,he85I(5bWXs'&pf 㙢ɜPxOAlpC u#~aCפM*>?t`p {6"&2ETx*n/@ 3vqC u#!3M\<ȗtr a2OLʶo8M$= ]C} @˘y/?[TIR.PX̜SQOLQQ ;!жXo%hb]'P4B-IH?(M[t`-bTvw:\ 8b1Q@{T;Cm @"'@@Wҝ}.3E)Of 91ɡbpIGLl{tډܐX>UǴ4\.GN5*V&ẂջAs \c{v5g|G_f%_Fyp! no^zזL, Sπt-]+: @jG31_߅];IgkCg[C02$O好Z{ceG~ns9&(A0vdzl۝ZuİLl8!XDz__}Ĭ}67xi'da}A l폒/!wm<ڿeSBav 7<#(m-8y#hfb_I(^^*Ȏ֝,c#ڂ538;@̣ t!Ȗ}h9hcU.|5{jReh *Lh2"4Y)iY/!WX-JC4)EQQLhhΗz^[W;wWރHȐ@}'ٲ"ܕtt@![`uT); +J@L秓0.{GPiHD9Lgkn^ 2dC); h3PJqWard[/+[}ZBN# ,.0@p¯C3]p}CguiN΀Tp\sj;ƂF> IDAT/'GS1* #h.o5QK)%h  x\86w_uSgRѨEwK_9nk (BoFd~7yoLC.(SOMf[[1aĬi8zAM-9ty0jeT?0?zsT5_U/[ygu`Y >DJs;Pێro+xbؕ|8m{>o' ߎ{H̍Y26G* v8  @wlPb5=om۟Z^S'qw}ku'5m*gJUc!"uX6R0WV[ T`oa6x=Z( lxR߉+ɖ؍051a4a軷j Xc:Grz) CI+[~k o@M3):7+>2&;nvVTkjZ>-U{hCNaXZf{3]RAɂn%Э=㈟GV S<3j O E|cKjTR?_D!~ۛնWʚn3kIkkQpKuGgI^ 2|94G4τ>܀/oq[𛛆o$`Li?BfଧËEOw&HKaB!Un(W}|6hB! D1Z.g?&`}`vD!nBCc+$֮%X!_(Z#4vnZ|5{DK B9/DCjç{d΄C!?BC :/8ޝ0g \XDBISYPw=_yWk] Eۜ BR4Tߴ։ s|w%Bl9<ߝB!a!4P}RX=!'iJl3d-2LBR}>0EF`-YN;WNHB@Hv e' @{9r!Bލ#Z;JfYre`J$<<'~|r,Ǧ8 Cc 1B $8XV-YWYZlߝ-Svܹ!ˑU̝F3w~s;7 =V;s>5qxJ whsu!5&6 Bh%O$Hk-zo3^Ϸ@фgZ%iosy8U+j,O!*zּ& +Yľܱ<(}zEeMŴYjf{Ug<nV;78W^p8ƒɑɑT(И 5ؠQ eLO]\w3c>]C\W\+@ 9jl|9 \DJHh qsow{-wlw/lpBMtQ(F"?'M2Qyɪy{?D̹73HPW%G4ѴJzgzUByK ?i?A::o\x}v;?řNypwpF~*JT|oW磔I65A߉񮿸?޴鳮Ui !%vxf_wzUAym㖭`wBJ2hlVTTZtoi}wYF*.T8[QY3QPF"o~=UgTrx灗 z?ؗ橨|_eEzeyWȏpwӖ}|g%߿%YT$yU()7ÙMf6Q(&5o|]pytO%S1m^Y3} (uRޣ;/7r=vdBt#ܠWNWVS=R:wOTu`*8s?W 6N QЄ묱@8m~,#S(i$>mҪH!4]%cOBgTJI:2yT@)ȗPgRu >#'׫΁R ]cH|^K9R۵毳h$;R &bҤwL2: P,#n_񨔎:K0RMcX19]?}Uh~Q0Fwtf)#7s夻~C=GT( 7hi$UdTkݯ9S('ұֺ윑Pu|CQ`b|:L,ٱÓs͑3ݡtzq} kTpPˢ ye$GvWsmf^9"p9z0.RJuGl:: !,#3ںm#4P%RN:Aq;ۣs΃}Gw|Gu78Cnt":pﱞ#۾:{&>V9f.р (~i$[/mbqˬ\6:K>9 "M\*Fj۽3ёv9\^6n+396#n0SnH6=j{y9\]ĺRy,:`$>pEx}Ϻϩ`JΡpE:<Xp):R#IDftIw,3kfRaqP|z8(jf;iu!&}:]9L\ tPcwMF!t!HG[fA1̨wGKug1\Hحu˗M՝;m781$@*<ج6I-|v˪PrO7{ZA(ŀr3UO(\ \QOG>96 JR|woX˱̌HPI:Z|C6sֺ_/sl{J ۶6.t]$CBQ)tdث4P9'7sۿ4XB+*oװsp__îDm{T` < 1{LMdoǪO )9t(R:+53ɐ(WbJ!9~@l됚8Pɷk_P^hWٔ%)ҹoP6HPai?^uQ t}I9m[0= ǶֳK ;ۿ+]lF`+z@uD%Rh< 9L=~:s78#,@ib%~_t46yPpS.lΒ?%osկ\*.64kZH|ro .0IN`23ɑ++q۷(K`˽vzǶ w"M=a9'ɋywc7![2t盦ib7/e HG 8$Au+=VF*.p!P!D{+bTf!-mn[317-{~ߊ+~ ݴ̦ttdث:ғ8Snױ-@=rt ǶsƗ nu4|YP6$K"jݶ|NS< &_.;b1uB@たcѾg`W&ط }Ęwn#ᮦK|i?aj9|{|xޓG9p6ǟ c.K)#=,PLl<3B)W*F:/EJxwed7@ѰLuG2Ll$c6oGGNb<&Fb~tPˑsDԯi>~J%¡?B _I/8{"b]zn'9rz=3߱rIaBF* E}w =3ab^sfKJu%ÅNTF| ߜ&TDW_`߷녿T\ٴH%M }bB&Tx@%l7' QwW&l߷sx]D&BlbTX:R5=2oBLB};f;g$TgsFsi[f:Ti޿L ^x>3>kE7k2b=oz0R<ӪUئqaa>ߤz~8)0b0Y^G˞Cl;.l:{d۷&βXw8VM:GI:)4Mu)G=NMkl$C6LjYB9:ޣs"ͫXhSMqft%mB`ۉu#6R#9P:ǚ&FT2?n6BY\:OWaf!UR:@HtBuu0]e+6gn_*Z-81w\u(4+zUɚ9~OubIiկ?Wz"kxaԋn?,yzCr9]VB۹L,=H6>:ֶ{atطWf㖑mCefݼTbfӑ~ܱ̼lSm׷~ϣi"xQ#q68_.LGm~߃J6^yO#'UgbKz5MDk,,i">wNB HDZp q$o uި: ThH휅7L>~YT2=[.Ľ Rq[fi>p*xe֢﫨`m|P+X Ѿݕյf]{{ y_:_aTb󮝽߮UuB ,= Z!DαwI{?8Ug"Ӳjשּׁq,`e};w[@!b]LrdMw|X4WW"XfníG]JYP5c̚GuhBÃ;NWBp߱}㮏z*f#D]Tae3YKnS!'~K'X)_W=kMw|ѕ[~Y!yzoOTXu(ճ߾w< \:K>h>}BJOUpedbíGWH2f/Y3Mm:Klcď/X|kՌ95 4MhwTܯ<站?:x]D6UJy{?N=2z$ت:9EUi o[oYx4W <>NY,~`=_ulFu+=ho%Y.TY|H;{A߉bET7ϹO[!{*r5}v|̴ֱS;o;g,|@Jgŀ&4]gc׃GeJ竬pw~d-wE7zּ&ߪxw߶7jϷ22ɷ (nXwݬE7S9fDZL=m[`߫?mhЦlp/y`=3SQU;5sm\6aFʦv.]`K*<ؔ 9#ȿg/Y @w{.5Zz&DBHiBBY84x18j$/P?JU?iTXtRaw profile type iptc IPTC profile 52 3249636f6e206d616465206279204672656570696b20706572666563742066726f6d2077 77772e666c617469636f6e2e636f6d00  iTXtXML:com.adobe.xmp Icon made by Freepik perfect from www.flaticon.com 0<5IENDB`AntiMicroX-antimicrox-b300273/src/images/axis.png000066400000000000000000000037041471077622000216640ustar00rootroot00000000000000PNG  IHDRVgsBIT|d pHYs+tEXtSoftwarewww.inkscape.org<AIDATHŖyVWm301 NmāƨAb1"в4t!REN֪CI5iHD)˴4Yl#;6 1}-o'9~sy>woZ!WiZ^RrRbACK9sdQ=W/lwLٚ˅^>- ˓3EGq˩?Y?<윻8UuHC` 8&x]Y%mi˵y┲K9OO//5KGyY.k?5H 1 &a;Wi $xu۴%-|9卵ECscvnٔsW4$5z(ؚnK!a!a)'|%CÅ'Mh W2-D Ͷ'1LFǓ׿@ !!( +ݓ賦!n#G`ƢDÐj`IHJbeC6Sa#m'bHxR78ai<6jJGW[7.JwP8 tg~pr)A@!p&m(4u+7F#=#F#3^IT]0+^!%B`)|!>>`9L*1x\f s$l|&@R2Lg'%QP@dAN֠@+ h#;i+Dԭ^)`[Z_y!HW=g󫧍n~ŘXq\O|@vji?yr7I]q~f4ʐ ?ך;w`ܐ PKɲ =P~>7>aCD| xJZ|/uk{`7_]1ٓyaΧX#`F"Lܴ1zA)j JkbͯpUsW[ٙ74\0a&nڎpU=bB1l|v=uyz #{G퉙NZIyGRVkbsɸG~W9=(U6xʧl6gm~x9{KMaKW 6KVRmV'Vp <4x 'CtZd⦒l ͞qt5|iTU׫z)|˥C!g3 πQyl{ /&SZ/\ՊlxT̳KF~~k=Йu:w0![t?Os=Ci4F~n冪{W]hn g QS7is^K$56O19A(@y=զ:2F#֦a)EkWkIlOsХ>\Is1rap@ixj/Mr3mk+k7X~Zn֐t<&CMJbAN<0<$ᬯ5DM;D{O?Lv\r=W-1;up3G(-*?j|E+9,XWܑѼpG8" SX3LIENDB`AntiMicroX-antimicrox-b300273/src/images/battery-low-level.png000066400000000000000000001102771471077622000243020ustar00rootroot00000000000000PNG  IHDR&#uzTXtRaw profile type exifxڭg:vcZYlv; Sk^L& ^s jTjn9[R}}Rgx,=z5uSw|}O9aЕ=u{_rPo=Lϗ6_(ą;` 0B绻ߣ^#t{~OA>-_/}=9Q.97. /Fz~LD[Q|s,~CVYIʗv5]s[9do_VCϛ/w|!+T276!mzUzWo/sToq;Gw޼כ~~(U2n+7xN1Q[9p\BΔq`hlv!l8G+  b>)z]wg&Be$+DXB)J&s1s^B%\J^C5\K| ``jV[k{ӹP\; ?ˆ#<ʨ>)gyYg}0*vf;.N8O9ӿ޶dͽY7S:|eWM)S8IRȘeʙ.F)gy"y2F v>fR]R9C~sfBw.R'^ܽK;`PXT?9gRڣgb?s=sԉ>MWc#Zn5Zi~1ɳEOh#SgIޠ2ʹCpZ޻5s#af89y `I|N$@ݲyL[+3ieJ5 >O_-ϜK; |R $8"?͞Z>Sػ_}-Ŵi!n!ؑ d6G+e"I>> T? xvϣ]ga"7`Z# t3J|L];N2r\,΄fvc|,q' 7Ѕz>\J?zg?Ŷj^IcSorJIާ(m{hvwʮ5|#+(? eW$\^UdѪ·Jeq㋻l{OOP0uB1Jatp;K0d.Q.am"(9Rakt *@V*IkZ j至PP+o뜍Kitj=yFU;Dڋ\ 2-pd;Q}уUH 68 e0 ҊP8wFl:wr me ĖY@FHxUcq5Bian[T'lÙAJ!"tvܜgqjT=}+eO*1''zfQKHD7(GNuF^uzӜz\Wnn@ 5ŸTׅCnz A8a#Go rOEIJ콺tSb\Pp\xC5i%* B2 I |Fٛj;5g{ `XQHc(6Ka5̜;mEZ?0~ӗ6yL+%w]KלP `Qp. Y£CʅY>]m!5ճ 1׏05"66ό*'?YshPw!:EAIN.f8Bl R9Y"tE7n!n!QηKK&H҈p6Ư&3ZS&Yj4FSEiJ0WVEAmX@*hS>sYfpa\dN \*sP}WMi!lbuT 3 j`x 5uG(8{BJ̦E5z798DUVJpzXكY$!W|pc74X۩;BHq=L "" F+&=mi =1j>R1[ xL"@DAچ t vI T1pdp6$^yq ֬|t1Bmҋ # dӄD!BͲu6w׍_hq#Bq ,}T%!nb|`XЫaz8seSҡr}BW#'.$B$5ӵ=>G#dԅ8p7U$@+"h@ ](6vLQ( WԽhJ5 MnCC1vGE ҫ jYF ,X4yh Hރ kVv8+`+k(G<ܟTpbJݯZd֛!U0H9 ݍD:S$[)1[:sxJ#}"N!T- d]rtLr"Ч vjުzQ[@0hq9)__'anXRS׆;S?ߓ[ N<sHzjX@&XΠA\S‹ڢ[4#etk, /!#d>9sB \$cش6d sD`4mYOc"ob%j귟oՑ$8/>l_E7Q*EY+M/)b5#prflFuSP|Xz|M{1TSWn@ңrkMc#j& @ z++G`|@tM(9H'Ut+7&R$]P*m{QWZToBJ]\wC]Q{b1v]~ |{Ӓ8&DH,+q=xZ=:" {d]g|oM}|4 q#X9>`>EWW859y}rf^BWjʑP-;A(adE^39FrMH wfP46~ @]W+wJFɂQDYAע*%bNuX:vo\%2{hx}5ӂ,OZS8+koHTlFƫ uOW~> br.N5# A q#$__OȱMҝy@rpҴַ|ڗјUi 4I< KbWQ=L )E3{UBΤJ .O-sl0-yǝaRw2#DD*x3G3ԃׇr 9CSHLSE紴QM/IT"ٕUJ{_Io0ye{E90{r;ˢH*Gz;jX15,W :>-yv?ꔏt=\tz;M^0A5Xi]Gjr AHd`- T"J-HD08i'܃4z@:CuEY|>lS24Dz/Mpb &}w{@FSSb$IӀ|1ch%h;pVP'[@]8PFp\4KNUF²bT &M"y`€ ~W&( ڑ!ıi*E~ Od?cfmD\K=1P 6 ۍOkNSë>Ƃ9q[MKsэqS Fa[<$! FU$W J=?4/Qی8xV _BɱjfR]F\7Uj@gq56$50jY;eK>*Bki4R /5"^dF\r}'c3. TTլ){@Jm?߽rwZ!N4u( 8sr4fΑ+ ý8ēdB1P& aȒ$_=(B4 u$"uH}n- _Wl\Vs  u Xm]Pȑ2X``MA|LV2((Iy55Hl[[U{sd;Z'nmwF{h)(u4*#U}Sv'؇?z(Z45DrMߣћ`0$@LP@K%XqMnTDNRY5 6[@p!"Ae4 "&jY冒 _@V`Q=w>"vmEOKZO_,1 aeiUQБuZ ӭ7ڭBKܣA2Aik+eѮv,7%l:mB\z8Yw˦\psXoCw{m 5I'jM1i#VMK 80-zm;Vi M`loGUzkZRe١w靶XC?7]$$C̿sl`'frfhqMa>pZT4n8ǃI/*λ M1sckf0UOͬvEk@JFh*#׳iݲ)l@gXQ/Wj}_ݑ-.Ni= PZCXmnPZE!mݚA;pl-;nI} = eh Nt +fbDDZ@*~~w*Q HNkS{D8D%+ ELLԷr"90.Gr.l5B; mֽܷ:dtcP^:uQݓ\Frc\SZaRT8tUpP{MAk P9i^D Ilq*X4htmt=8Ǧ23˾. !txGtmU^IgJzr=4H=h]Ȉ !, O΀q׿Dp:^ Kl N)]il,.7:j#=E8Tp5g|VX5f]#!?K]Z|dVH>~\ZOz 5Ę>m}`Gi%C`1ءN=`?`P aU^CI2?[('Jv^xrFs2̍*svjyvo~J4E)Nxy<ho]F˻Lӌf-e+})=bnL|S`j{ XN Ū'hCݹO0P[N2^Z]q3cor8<0Y#r O= E}FҿFɉ!>oۧZ\ \[~/?N+D˝\_0xwDM>Ht;UavB#e x{tQmo#JN׈=PBKAHIT+=7!LY_E=S柵^hi=8\cCzK= @gٌ9KkJv\ qz\)TZ!}qC%JXܯL Y;5 #8n6ƖdfkfY;o(Rh-SވzT+28k7 QISn@)7`g2j}$V>nH&O/5 vJzH2hvs8WX**5mUFqZ<}-O3YHFd(afn4mKaPOfv9 Ekuf * Zԓzj'Ķ{9\ko8tQ{K|16!*lQ[? RT\W$7x:],!qCl WܴGmYÊZ㖶෮G 겐:J 4RZƏks(*44 \w42;D. xFY3 nY+!GHGUBRҦ Ͷ TZlJh3C !dqէӔ=' (=ڄK"v2m,j5rXU;ۻ;5qi{q x6Fc1z7i q,.e+) .hz\$^z&МZ'72=\] ]D2v/MdE3ϛt&O@4t&v'^DLм}.d%!-B ,<=rbQ)tYuΣHxר'D%oB(;znߴs1ZkwS!羂f0}@ݲ)6rϿ).@jb;,'VS6,}h~_qAԎ䉏p\pk`OVNvU<:Mtz& . w;qcV8\==n 5㛭_YЕShakV+Q[c j/A9*܁.ܵz4P_=<iCCPICC profilex}=H@_SEVvqP,8jP :\MGbYWWAqquRtZxp܏ww^f1e11]^ы>ĀL}.Ls|׻(>*9>xEATH@tuUߏTݨT((J(" bV _}#+ m :h6h6Qc6IqZBf"Ѻ/-[[W`u;›&lۺ }}(DP̑ R/#.JEPJw JȔ++֭[1z9fkϫ o.Weͺ5x'VEsd>&oqiR o{۱f͚@՛c j8f| 18*aGsF˴3pᄹED,>V#oI_`fҝoPR`x:˃py<^b)eJ hfRoC0La4LX۶a[aYAJ@k;vS'QAӌl_v]+¿mͪ7 *u4M4M4uZM_Õ\!zP`@i9ZAq67y0BJ0-T*]TP.QtA@l}i8YV |armVΡ63 fJ JWy/y1 "arjPJB)֭;@;32KWl/Sp8J/igJJJjV|cD_W ZIs&Ru}?曇Hk˕mI I2 T3"gt#G_2>86mĿfCb" 8ۂs&&'077=ׅ\u8Oߺ = O `8%!D2 %Ȁi0 C{?ހi 0`LLVˉ&y~ ۿ~RwHVoe7,\p HѹwҕRPҏ3~Qm۰ 6 ˴`,˂7 $|gwSTm+$o\Ejjq#pgB$<^Nph`"L?"._&Oo5;vly?yo "%?neK%EE X ;v 'r)f+X'._Az3ku< hl^Vf1;;Zmf%| VDѷ0hoU~ofO|nsƘ7OKţh/: 5DoOPTP.Q*z*\\!Kq 9^"oT9!|`)x q}Cmv33pNs/$螱JXp? !?͗786l؀/+gF>'wk؎0 ׋^tw4#mx'ROEE/ւ~Zg&4f 0118~8Nffpsts0L_=^o|]oC?yޟ*dyiDuߏ߉kbժUm$|AMl򿆖tUM55Wfsɂ(y."}Bf< E+KMX0 M/OJ4u_˜>Çgv67C8K ?zٗ%8a5n*YMR mo͛ftD5WԊ8" R~.\^<DӂQo;is% "p)ǜcLG ,3 m,+A_4U e4hAn֐R Ĺs /{Oa`:g }?_>'?3N/2f+ƍp` 0-3VoNV zzfsss\q ␠`9 BfqzA(I>XѬ#xuHѨ1S?7ffh41mR0Mۛ8vNC< &.rvNsPUJA].TVtUUBogiص)z#>B|sz~?c68~>t]t Ww}/LUׂΞ= ` XMJ)-||Ҭ&qQ+E=)?j @sNY0'nE6`}*`CjpzU튴L695/≧v#* lz 7C- woe8yNTB{w}u]8qOGPvbՉ{hwq M}۽ =p\n)_zoxY|ٳgFu8Mg5Ks^OTڥ]bmpRݓ,vӾ@j%',1&Hwy4< utCJSNarj #WmNg* HB|;n?Wj;j?>&h=~꽨v' A":v葉1>nA]?k^ΐW{R׭߿67Es~wENjø)Պ9𸮋ukfED?@I$%K=hao)Nu1d#a/٨!+3L$)f:#92M_ $}wO2-O]q9L޳,]=@lWL֏n'Z^&tNچO-lgYs32%ܼHr$LBIt ij;(F[-}ZN V/-DW|Eb- pDDZ6)C6qV8Phmd5MbdYTt}R9> qtHazg?&RXdVе Ѡiq+/m{HQ&=uy_2 ?ar?sN?9sNl0{rN\b y7-ŅXM 8r(V2Ps*5슖Zy睶rW|s&Tn"v`~ήD6Q]nG#'$%MȜ87 ۲P,()->  6a&pҍyFLӀi0Lb"VJGfM[Ӯ([D@^ܯ5D0!#zzLWPzL=wemO#JW@\x(Mfi|WZ'İ80Db0 !`~7IͰm?Os)A#ʂ8՜8A0 BE i6OjMZ\b_@/rw Zͽ^n).T|)y/H.JX hŗY jMS^eh8 #DCO DJQx)N-u?*kPt(Qa=*J ;'BTkcB^eb$n!eAOA(b`M^K-Gtj1j'cf/ l\1Xrq7xH<:0ɷJ;8[H"pZcDr9Κ895z3ylސ3&c6)41ʍi䓩iʥ<͑rm x*l9$ 83J)LUqC6(j%Iz~uUCaz슟&kLgb <4G)rIgcA *hV gG/#׼ҜX9i3..̙Uj߮%BjuՖȤb:>!wF mL/T6.tB`X-͑r{I )}@Q./l+9BL72 r:%0Ygߩbf#ߔ8k0ugNBϭHJvn*v~U[[qyqjS}Byfaf9ԜZEJgY'e^h/67s.8a<(jZb~T6W|9 jK*<ϊx+t&!yg^r# x>f)+6ÜäQ>|͑9>qT8Չٴg񫔕KՄS@m"IŹR)ה+Qly+ÐEUN9OQZQCͤfvj6 דQ]ڌϱ9T/[$ܬ1dKe6nh)c %u*\Ȩʮ)Ag08ה[w>9d=σzV:Ċ12Tn^|)t)ɿc{art 8qfL@^h6[)bR0.XY)]8 XBg^*]yddR ;'y.6emZ#tࢳ`i7o2]1!/t{TnN|Y&Q'dvHjZ/MfLVJ ̞MÈ8ۓDF$aAڃyocn/KpDYQ(?QߞDkIQ*gV䌩v66Nq<lFQ&­Zr n{_#e!bT*nL9q̀NM26Ov**wm/ŎeLOʩC@D=]i1=ۋo_^#TnfJk/fR*N!izo}g06ҭ;9 f '8^$XRq/JP26}lf,Q ;9vH]S܄bݒn~l|]7yy#ݻ(!8囈P)͡"iQmBAmN9XWp@5;?gϣ6[Oslh4}'O 4HZydg|mo}\(jȍg:lBxu9r%%4GNN9{?ٹFB$ +I^Rw^8usp/3Gܪc*RT.s]t !וΜM[%PkVS{cclb-N:H8D<4\* ;Z(](eB L? "/cfFtmr[6?|nxr/Q\ IDATe9¹\ 1yRZ &혣]=[O±hJ) vnmׇR02@N^gm8"Ir a(rDk R$Pl\48k0q^x~gBJ9̯{sǃ#=9mq9Y/7\ 2e? 8$Clݴo~}vJe(P\~Z~*=6\*a1 ^M6 @+]k6W< ~'g5|{w7/uY9*sKI_@rs|kI_f(x߻߉; ePAs+ފJ6m>lA/@ؗ~/mشy6mކwfg%O/͜;kxۏ~SAG ed5&*<mWJx<HcxU?~#uA2?qZɩI຋a#kNi^/‡i;,#*e.bOfS$ \O1ch֭Hٶu ~{`.I)] uDoR9x+:an._ypF93pS.cmOx""yxt][7VCb߾ ]۱>)C<7/_J_' wNU44JYTZ#NÇUfb`jz5b! J35<ԓל0ݸk.œؿիqˍ;u0pW* $'^д9Q'IevX"_cX`ٳFRݏ{l쏘C"}ܭk{Ʈ28(* ru@aL8ChM#-Bofh4px[o B \SO)+%mJ88~x$;7o ůrt?"%I)-&)&V_ebm8:ZEيεefH闠;w6FVbㆍPJ0 s=ל/f/JnhV,o!+ A͔Fև=DJVzu"p7|0cff{//>InFGF8=5ɉ(1txxHK;`hNoV)}oC/j' R*+Rzh6h4Aۚ?[,=Fٸap`0;`([T*3c* ؅ mz{mn|>Zu]uZMluJ 'A85#0i;41a-@Z4+.̵yWXs Oɣm R:ZN tZ|vmw`"Pw4*MRL\y$* %(7i6Rl5. ptuUc!bIJ,\kzb88-9=Y*yx<'fb>KPvZr+-{9J!lڸ rGm6)J'Z-϶{[3k"_&>VD^GίM 9(1LK6l5'$hgqPoe3y5o03 +x$?qO!AjUX f^/u*-+<]VyJ)8-ve9v^v%11}li(nA)q UK: Q t*058&<]Pf&vxc@*H%[? _btš50yᇀ P\U*]XvlYkL1_zr j+M!&Zּϰ-oq~@$K0VAW(?y:RظacNGZNdB3*Db#ϓh6p'r#[݃͛$J)Q*a0J%5 J5|+ C8pp"]$RK1Wk ?ߩV_m:Uk~G䯅8{ML|ë w*tWx,#MKm.w 8Tj%VQ0u]4<]QrkF`dd4AѲRMGQR b%`hXs#h^Xs35^/z.a.e$"v퉘ߤo00P$$*02S8X>~t,C*^ at 84xqyr9;mmסZ&}JILN|@, /Am1=Xo@ɠcI{nز$csht8quHOf2j;e ˴󆝚Y`π@eT%lSƳ<7IQ)+9 !}BeuPp9jE_rw2!rv뭷A0>ϢT~6e}@?b|zkZ_aLL^L|p]㿦gf`&(J_p0d(uon[9̀ 3yݽ Wgf,$;?ˌ5㘨} 0X`Q8}TG|f)eI튷M[+qhJa׉&ݮ5 @T +8`S`OfXsf1#tU ~^୉hOw.Lq\tͰPvMC=ֱjcm֮C@ vmvFJ07 UO~Q(UL䙭S/^!Rdw8!UgKZԲ4:Dᆝѽ*aêvŮ .=80}=wBRF3^`͡uCܾNar9Vmv]UxRS ns(U{,Pv@8,0 Μ ^KX;j8/Usp'j2JJ%nvV(uVx²d(H(QA'96gmt֍O>Vf$paUEmVj53~y,mV)़@G$ɚw0U1\ԛάR*d2֎>ÇvS%rsv=Eҕ|`NgsUPB\Ӄuk%3!eF WNe" ugpq[JԜWʕ\KAk-W*ʝn''viM)סEnP /V1"5L 4&v`nnk텙QzjrWukAp H dm|\4۝v`X!P$ 402==*'mp̋W\Z*SgxU̪hhrHQ2):Z#"\Xc9`̥9_ gU]g[ٶR < \EpI OJX$@4Yڅo^5k1<;4z`EI:*^"w勝rG;gJ[HEPuLP@D݆i@Yaf_8{_d4A|s` Ilܼ 1(f_H|)5F-ꕶ*W؉X%t׏ zO`E`xpZ{v,CX(= Ƞ [m`s0 :wP(us:AAQwU;Ns,%~p廏0kP61^ۣ1%2VS(UC vbAfRB7הkfЂi -u?"9&m9ޞN>sewLvCͪ,; B>:2PP܄šC*S?G%HR.raMk :6cxĖT3r#,TWZ -۴F ~ޗw0-?` s(2 c6K_A4`5?NU Be%q)]e$K3,84ݬ|:7{/eㆍm[[-#3t H90Y(ȩ% T0L@\ึ vl f21:H*]V(ah} %`dAd)/iDnY`m(D)F(y$x\VXnۯ?FB0ZYtY4;Zm٦R܄YG u`H C3M2ǡT+aV,A.4Fwh ` ={ƿ>MC W!B<܁fg̪N–* ŪUCZ;O@*@z{1 &L) J b\*%!&,ہȘiSJU A(nyltҞάR J^F̌V[ef!/X=h(Fz Y(v&cIh²9(-`0l?c'ڌ0EjjVܹA@ KqW uݕhh60j5*J$\J)H4A8֯;rF@FOU0Jba[arA*&"MRÃ.n(,k:1yu+x#A:G5OX*\pgFbk400-K{ȗ8<{"2|D UB L|CL)a@R6l 7~V+ g )X31iV1t 8~TKP.W#, koij&E~kלCZC+EBZI`+XTÜ[`FԀiH HòoyDbtP,sTXB& -<Y)G6]]UlX1Z3_=,V~= &?2! dXl0V9X& gͦ>f2cd|㻮^縔$+}AM]Y?ϰF[nDt̡ZF=J Ь"kư-ijK~GvPl4r[ؾ'4^bӫpa?%"4MXyźK9KYo)6F[J%e cxx8Bڧ5([м:`nF>RхiDQ%x R X5}ce,FR5P*_Ý!GyrZW-O_K\yMQd7$ 08]ZX6gVܴMgRO1X7P(0i#5:(Ax Fo-gqÍ=x򉵑PaZR(+8wxPjajjP/MOOOO'Oy %Pva#(W=q/m/dTf"$/HThAGՄ;k~H;˒Ts(_pG;9^U͑QP+Ϫ c܂]k=~:uO=```y=x?Eo4ϼ (<(قȬJV؂ 78E/LJQbm`bb"x]==9r|NwCUwggg1>>ZmΞ='Oi5qX=zr@ݦ!0K# 7uǶ=XEI B1?2,{fq-3HWhQ!:1BK _]֟0\4.\G>wI{OM)ҼtiR~_(fr2Y:PB@"aIm(V޷w#N:sg]ENF]|J觞܍׿Ek&U|8B骃Z0;"z=fG>փ-['UUQ N'<:WAڏ xka*VAEtr=FSj C#.":aj:ivv/;-[6_VW`A\VLۑG~ duV Lc!ݙ_` ,FobWq-vyab&eN U%\uh߻{/e=Z.v>G9Vq8 (p7͢\F9 ~ZcFocYsz\2f TƜK< ۖ*ƫ_ |H R× 9b:|v!/*33XзJ°USF2nZ`C-#lPo&vw7 M_jWd,"r~G#<눮pk;i@G-%4/=sOIg[| a|#L8ـa3M)  Ki\vJj\I3plgnFҺ~H' _ !%`H r=Å\6ҮbO&lxʸ&ݽC?If =nۅih@`tu݇Bmmo£ߞ38s,F׌\ZՁ\ѥ(x!Kq`.ՂlA˜5-p\! CIӪzvd\t)ch4Oop[~@M‹&̴gY{J4ƶ=AC xw]5ÄPQ:> s 1)'1ma#~Y UmP1 ẰZVFހQQ 6L-ř]s|i17WSOɼ_b˖uk^3F }ap yiiU\|ۄ'}&;[\B'ggV?$:9ؓΜh6 yd\2"\pR0{`vWQTB >|6lw6^A!RȈ_2B70$$0d*e >.O*%=_$:HU :JSS(;a>y#"@)Tfеu+720JBbB](.` 00p||W"{^|ۅ 8z}_̠X ﲁb]Uq{/Ml W)ӷl4 IDATJ-$pm䢨hA'Fȉ|AN ʧϠ|px5MpNA43 Qf-֢~T]TP*Q*`JBĨx:Q u L$ K`Y(}oq oͩZK:#Pbhó׳5?:@߲\a΀~z $gK~Ss>$PFx}V+ R ]TQTPeB50W/qy}W UoQX&HJDV #Xm+W Ů.3XzDFdPFO$S@)|{й`S{`Ytw 6B_3k&?a*_xxVBJ&RV ?yir?-#2HqI@ 18Cp C*0l˯Q+cczCm_(+<ѨE~m@[b_ŸY-~j`HD]Ey2LZjatvۼJE倃Htx/k Mx9ș4l2 @s(RqZm{v?v_ŦuT+> 5$N4qrGKxX:eC6ΠwP0aRY`O]'!" Hbئ VLzH&_'A(Ԧ h"Y8xE <QN&-68n~}g0<G.N~n"ۙ=?>>l4r9h\-NmI(ʖݙ2'{F "w/LtA\@ $ /I/qljq.3w]׿ش1d/=6gy)>F{p5=w8pdB_(Yu4d JrCp ! Sue0jf2OMu^izC{MSݖخ*`)SG2lSeՙ*B9|ID .3x`l3cfffOr^OU#vzRzzD !jbV" fSx.k2 Q0-AڽG gKϟ;ND<<;Qƚ5J2THMjht|[U׿Ύ-d"dJZ"KmƩ,Fo=p&(,R:K]'hϊن@UZu(UKT`[4 S6 ',O(3g^E3,q TGw_h FP.YhSB$AO ٰJë_ u&Kq4LS${NyhNԑ%JejсNΝ_YiӋ4~7 …q:rs{ԅjR"`$la2 SB C0|f&BJX-FsIs߹7^.4<vm/Eؾe7z&+ r/ wE"gFOL:^lnvЊ)xmo{4x \wȔZt {x`ŘlyBpф oZï}ϗp/>n;38y!8$vuN#w(b"-#6wgpm2Ұw?f/m=8|Ю4\nXE@Q`UqG+H R*BC@{}<"mϗš#GpOt#h>_ͱ6 ?JUb& ^?z'm=16Y&Ե%=vz'(2>Kw-n%FPUqD%`cg4׷E5[ؕB&z҅Al_;Sg-"cnvo"tx*NJz\{ KK? lAɺ)/8j]4RY~zcɍ$|6ů2a Ю1>qz*`l5w:4$gcw)kHm x 7*>}a: x Ď۳a)%%qأo` hM5*#SKO7uS3o76p`}s+k^YAke%wJ߱(r$-'ږj{ Y,GZso}W9T [ݪ}H|hf23@ٶ8$Sr',`-꠵ (! ('f(tR$ɂV\^[k>dRwed6?`*s  02`bC*N!]}}]|"< ~Wlw.1\]աCx9 7PߣN D+TSNJjEfEWNӔ Db-E"IE~Ǐ=ݻg]$")K#7Gnt ha4@٪޺pB{8Dg0@{0@kbG !n޶ewjDlI^Yzq/}{7g?}(&ΪaTDᮺJsyfO=pHPYASzJ@=Q̃ZᘪjL׎Ѯk-wZ!zȴiտ;8|VWWY7/:(C fJuݡEC )ZMj%U&`E/`r0$S("!rf3Ϟ_^yG_o$_~T)=AʉV3e5m5`Xg&-?r%c?jTǎ>SjI~հTUH1Pv[NhPRa(=d&8B0!RD )a(@vK}ۙݻwV /'x=9]ӱ>hI@ێmÝNn{΂c3bd_#}ī_J66䋋X]Mv-8k" AujC@-@ GQ|~U}M?Ӌb{mOw*:`f"l8bPG`,0Dj.J%:-L&7 k KRfC[Y=vny)}U bvLOwiZWU6rf05=@2sC CfQוu uS [u]u^omWuiNuKK 9Lm+d9{.:ZEAp'3w2 Cn 0ɨD0Ad#M"d$a$ "DR4P4*^@fb- ,EYt˲kE$ =f^ B$AJ$ G4AD*U혙, H>lʺ,1r$ĩ'1lhŹO?я^8`yj 8zj- :IuTJj EHB VdD(9eI E*^η0eengle;3Y>`(7q `/ITU=caf?!W3k)⹉Lew1Z{/7tޠw5K诜Z{SJ:bKj(*J R* *0 [A%1RR!BOH0#<2sɖ#hcG`Y0,6jΥuwih7|Qw 70&ݩO=Hwvu.I.ܥ[^sLuk+ZYpV*?0PY"!TTB$&,B)lId(;)6r[T` K@i9L#KY2@ 4.QyR рcGGv;$x1+2]fvA'bem3¢cq/_z+nZw@ymOmjTEp"$LJIdBHh,圫EkI; 2YCLR49,P9؊hTÏxF Ks`!A ftG??4|ke~Dw-/z6GytQ?n7B66♳CݙՀX(Ȣ)s3FK2 g O`"h JI s;.)kx6pDQ渨I FUY$\h] MWb~:sv g&H?{8?\={ ?f+5Xmz`~a2",)XȔh%TmyA'&(Sq4k4v8[$tmܗۘϴƄ$~_a LU8u,V7r1VD\=3'wk3 %0; NkbgN'CpA^fDJ,צ:ѓ ZLEI"0 ـ"G+}l8A<> S*G )`EJ*qՁ=v\hRK˫8s~es TQ ]ޚr*K;/= c|qֹ'fK9a IDATeAYUլX2 4k]#i b2]$#C$- \PMi%1KӪ0"D3!J O9aDa?G?+ Ba 3]Luh%R.C{eVDk {X/P <$= 7,Zasyp#:*j&}biЌ#Mo¯>[|leHb$QC46:bjoc l*$Ordjwx%,ά]nwѤBNEN."Fe0i :AFPrܠ&lU p`#\T{Ї9~ks~}C^=,,cOȌaeP%ceׇQkZ$Z Tb6ՑLʓ-I%S3QIRa3 4 {RfЀBVHsd6@.&@X)=x)nQ< Cy3' ˠFiĀ)+nZdN"D A Zxbr0wD]˔$rp=j\na +wpDm2ه$$io5M]5 crxKj9FQe|U#!I HD8" K!),:i)!CЧXY=qnyO|o}^r~+^&|统Y|QgmU֪HVNU09 :aEHc 3tZ AX8!JmK6 0df K"*yyPꎭ8ZC $.L,iH.Ӏ"` YT3jJr>Zn;LCT{`u" |Sl+YXw/cx㭷raa'{=OM1qK3>=EZLr! }˳}.tRnt|pc߱_?R7?꥗n0}D~R$<'74r+(@+M?3\KIlV K&+4=wkeOwG{(6\NQ*% >ZCo86 _x`SwmzWBْS q+Bv)Eܢ.<#47"zg/7S,d0'zP}Q~3~@i_hus~bנZ\(s#L7W0 Fo?ҭyS^tk&Naa!2ws#آ5TE%p`& @QhV7|hsXo|7 (c&;@5cx,$+`=]5L.e?.Fv h7|a6zE)U(]JJB 12枧ٶƦA9::pDĉ]rLƑd ̈́B}QVhhWVwVĦ%!ZC+F} 3j+hh"ҁiUdDAhYFS񋅖NjngTkXp-K9Ys U[ sa>x) "9w4F84E% tS \ZDp R`mJLqۃ!Vjh(/+`mV"x9܊ Zý%+B;^1t"t'øP܂)Ǧ&R0\̊aP঱ YOmxu2R;LyZ+R,v,#Eaܱ__찡l]7Sz3:+czF|n>c悱FV!/uq{-Zg^Jގr4K73Jl$`l4*#U15]^c{=moO 8w@Z3\72[Xl 1_Cjk]S{V3W=e_e37k>^dgPizz`5>!;osUkdن z휛vL݊yFb+٤^tPu_vuʩUoy/^Et׏%FI +ߔ矏pw^8IENDB`AntiMicroX-antimicrox-b300273/src/images/controllermap.svg000066400000000000000000000474151471077622000236230ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/images/lgpl-2.1.txt000066400000000000000000000636421471077622000222160ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! AntiMicroX-antimicrox-b300273/src/images/lgpl-3.0.txt000066400000000000000000000167431471077622000222160ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. AntiMicroX-antimicrox-b300273/src/inputdaemon.cpp000066400000000000000000001374311471077622000220010ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "inputdaemon.h" #include "antimicrosettings.h" #include "common.h" #include "globalvariables.h" #include "inputdevicebitarraystatus.h" #include "joydpad.h" #include "joysensor.h" #include "joystick.h" #include "logger.h" #include "sdleventreader.h" #include #include #include #include #include #include #define USE_NEW_REFRESH InputDaemon::InputDaemon(QMap *joysticks, AntiMicroSettings *settings, bool graphical, QObject *parent) : QObject(parent) , pollResetTimer(this) { m_joysticks = joysticks; // Xbox360Wireless* xbox360class = new Xbox360Wireless(); // xbox360 = xbox360class->getResult(); this->stopped = false; m_graphical = graphical; m_settings = settings; eventWorker = new SDLEventReader(joysticks, settings); refreshJoysticks(); sdlWorkerThread = nullptr; if (m_graphical) { sdlWorkerThread = new QThread; sdlWorkerThread->setObjectName("sdlWorkerThread"); eventWorker->moveToThread(sdlWorkerThread); connect(sdlWorkerThread, &QThread::started, eventWorker, &SDLEventReader::performWork); connect(eventWorker, &SDLEventReader::eventRaised, this, &InputDaemon::run); connect(JoyButton::getMouseHelper(), &JoyButtonMouseHelper::gamepadRefreshRateUpdated, eventWorker, &SDLEventReader::updatePollRate); connect(JoyButton::getMouseHelper(), &JoyButtonMouseHelper::gamepadRefreshRateUpdated, this, &InputDaemon::updatePollResetRate); connect(JoyButton::getMouseHelper(), &JoyButtonMouseHelper::mouseRefreshRateUpdated, this, &InputDaemon::updatePollResetRate); // Timer in case SDL does not produce an axis event during a joystick // poll. pollResetTimer.setSingleShot(true); pollResetTimer.setInterval( qMax(GlobalVariables::JoyButton::mouseRefreshRate, GlobalVariables::JoyButton::gamepadRefreshRate) + 1); connect(&pollResetTimer, &QTimer::timeout, this, &InputDaemon::resetActiveButtonMouseDistances); } } InputDaemon::~InputDaemon() { if (eventWorker != nullptr) quit(); if (sdlWorkerThread != nullptr) { sdlWorkerThread->quit(); sdlWorkerThread->wait(); sdlWorkerThread->deleteLater(); sdlWorkerThread = nullptr; } } void InputDaemon::startWorker() { if (!sdlWorkerThread->isRunning()) sdlWorkerThread->start(QThread::HighPriority); } void InputDaemon::run() { PadderCommon::inputDaemonMutex.lock(); // SDL has found events. The timeout is not necessary. pollResetTimer.stop(); if (!stopped) { JoyButton::resetActiveButtonMouseDistances(JoyButton::getMouseHelper()); QQueue sdlEventQueue; firstInputPass(&sdlEventQueue); modifyUnplugEvents(&sdlEventQueue); secondInputPass(&sdlEventQueue); clearBitArrayStatusInstances(); } if (stopped) { if (m_joysticks->size() > 0) emit complete(m_joysticks->value(0)); emit complete(); stopped = false; } else { QTimer::singleShot(0, eventWorker, SLOT(performWork())); pollResetTimer.start(); } PadderCommon::inputDaemonMutex.unlock(); } QString InputDaemon::getJoyInfo(SDL_JoystickGUID sdlvalue) { char buffer[65] = {'0'}; SDL_JoystickGetGUIDString(sdlvalue, buffer, sizeof(buffer)); return QString(buffer); } QString InputDaemon::getJoyInfo(Uint16 sdlvalue) { char buffer[50] = {'0'}; sprintf(buffer, "%u", sdlvalue); return QString(buffer); } void InputDaemon::refreshJoysticks() { QMapIterator iter(*m_joysticks); while (iter.hasNext()) { InputDevice *joystick = iter.next().value(); if (joystick != nullptr) { m_joysticks->remove(iter.key()); joystick->deleteLater(); } } m_joysticks->clear(); getTrackjoysticksLocal().clear(); trackcontrollers.clear(); m_settings->getLock()->lock(); m_settings->beginGroup("Mappings"); QMap uniques = QMap(); int counterUniques = 1; bool duplicatedGamepad = false; for (int i = 0; i < SDL_NumJoysticks(); i++) { #ifdef USE_NEW_REFRESH int index = i; // Check if device is considered a Game Controller at the start. if (SDL_IsGameController(index)) { SDL_GameController *controller = SDL_GameControllerOpen(index); if (controller != nullptr) { SDL_Joystick *sdlStick = SDL_GameControllerGetJoystick(controller); SDL_JoystickID tempJoystickID = SDL_JoystickInstanceID(sdlStick); // Check if device has already been grabbed. if (!m_joysticks->contains(tempJoystickID)) { QString guidText = getJoyInfo(SDL_JoystickGetGUID(sdlStick)); QString vendor = getJoyInfo(SDL_GameControllerGetVendor(controller)); QString productID = getJoyInfo(SDL_GameControllerGetProduct(controller)); if (uniques.contains(guidText)) { productID = getJoyInfo(SDL_GameControllerGetProduct(controller) + ++uniques[guidText]); duplicatedGamepad = true; // previous value will be erased in map anyway uniques.insert(guidText, uniques[guidText]); } else { uniques.insert(guidText, counterUniques); } convertMappingsToUnique(m_settings, guidText, guidText + vendor + productID); bool disableGameController = m_settings->value(QString("%1Disable").arg(guidText + vendor + productID), false).toBool(); // Check if user has designated device Joystick mode. if (!disableGameController) { int resultDuplicated = 0; if (duplicatedGamepad) resultDuplicated = uniques.value(guidText); GameController *damncontroller = new GameController(controller, index, m_settings, resultDuplicated, this); duplicatedGamepad = false; connect(damncontroller, &GameController::requestWait, eventWorker, &SDLEventReader::haltServices); m_joysticks->insert(tempJoystickID, damncontroller); trackcontrollers.insert(tempJoystickID, damncontroller); emit deviceAdded(damncontroller); } else { Joystick *joystick = openJoystickDevice(index); if (joystick != nullptr) emit deviceAdded(joystick); } } else { SDL_GameControllerClose(controller); // Make sure to decrement reference count } } } else { Joystick *joystick = openJoystickDevice(index); if (joystick != nullptr) emit deviceAdded(joystick); } #else SDL_Joystick *joystick = SDL_JoystickOpen(i); if (joystick != nullptr) { QString temp = QString(); SDL_JoystickGUID tempGUID = SDL_JoystickGetGUID(joystick); char guidString[65] = {'0'}; SDL_JoystickGetGUIDString(tempGUID, guidString, sizeof(guidString)); temp = QString(guidString); bool disableGameController = m_settings->value(QString("%1Disable").arg(temp), false).toBool(); if (SDL_IsGameController(i) && !disableGameController) { SDL_GameController *controller = SDL_GameControllerOpen(i); GameController *damncontroller = new GameController(controller, i, m_settings, this); connect(damncontroller, &GameController::requestWait, eventWorker, &SDLEventReader::haltServices); SDL_Joystick *sdlStick = SDL_GameControllerGetJoystick(controller); SDL_JoystickID joystickID = SDL_JoystickInstanceID(sdlStick); m_joysticks->insert(joystickID, damncontroller); trackcontrollers.insert(joystickID, damncontroller); } else { Joystick *curJoystick = new Joystick(joystick, i, m_settings, this); connect(curJoystick, &Joystick::requestWait, eventWorker, &SDLEventReader::haltServices); SDL_JoystickID joystickID = SDL_JoystickInstanceID(joystick); m_joysticks->insert(joystickID, curJoystick); trackjoysticks.insert(joystickID, curJoystick); } } #endif } m_settings->endGroup(); m_settings->getLock()->unlock(); emit joysticksRefreshed(m_joysticks); } void InputDaemon::stop() { stopped = true; pollResetTimer.stop(); } void InputDaemon::refresh() { qDebug() << "REFRESH"; stop(); qInfo() << "Refreshing joystick list"; QEventLoop q; connect(eventWorker, &SDLEventReader::sdlStarted, &q, &QEventLoop::quit); QTimer::singleShot(0, eventWorker, SLOT(refresh())); // QMetaObject::invokeMethod(eventWorker, "refresh", Qt::BlockingQueuedConnection); if (eventWorker->isSDLOpen()) q.exec(); disconnect(eventWorker, &SDLEventReader::sdlStarted, &q, &QEventLoop::quit); pollResetTimer.stop(); // Put in an extra delay before refreshing the joysticks QTimer temp; connect(&temp, &QTimer::timeout, &q, &QEventLoop::quit); temp.start(100); q.exec(); refreshJoysticks(); QTimer::singleShot(100, eventWorker, SLOT(performWork())); stopped = false; } void InputDaemon::refreshJoystick(InputDevice *joystick) { joystick->reset(); emit joystickRefreshed(joystick); } void InputDaemon::quit() { stopped = true; pollResetTimer.stop(); disconnect(eventWorker, &SDLEventReader::eventRaised, this, nullptr); // Wait for SDL to finish. Let worker destructor close SDL. // Let InputDaemon destructor close thread instance. if (m_graphical) { QMetaObject::invokeMethod(eventWorker, "stop"); QMetaObject::invokeMethod(eventWorker, "quit"); QMetaObject::invokeMethod(eventWorker, "deleteLater", Qt::BlockingQueuedConnection); } else { eventWorker->stop(); eventWorker->quit(); delete eventWorker; } eventWorker = nullptr; } void InputDaemon::refreshMapping(QString mapping, InputDevice *device) { bool found = false; QMap uniques = QMap(); int counterUniques = 1; bool duplicatedGamepad = false; for (int i = 0; (i < SDL_NumJoysticks()) && !found; i++) // for (int i = 0; (i < 1) && !found; i++) { SDL_Joystick *joystick = SDL_JoystickOpen(i); // SDL_Joystick *joystick = xbox360; SDL_JoystickID joystickID = SDL_JoystickInstanceID(joystick); if (device->getSDLJoystickID() == joystickID) { found = true; if (SDL_IsGameController(i)) { // Mapping string updated. Perform basic refresh QByteArray tempbarray = mapping.toUtf8(); SDL_GameControllerAddMapping(tempbarray.data()); } else { // Previously registered as a plain joystick. Add // mapping and check for validity. If SDL accepts it, // close current device and re-open as // a game controller. SDL_GameControllerAddMapping(mapping.toUtf8().constData()); if (SDL_IsGameController(i)) { device->closeSDLDevice(); getTrackjoysticksLocal().remove(joystickID); m_joysticks->remove(joystickID); SDL_GameController *controller = SDL_GameControllerOpen(i); QString guidText = getJoyInfo(SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(controller))); if (uniques.contains(guidText)) { ++uniques[guidText]; duplicatedGamepad = true; // previous value will be erased in map anyway uniques.insert(guidText, uniques[guidText]); } else { uniques.insert(guidText, counterUniques); } int resultDuplicated = 0; if (duplicatedGamepad) resultDuplicated = counterUniques; GameController *damncontroller = new GameController(controller, i, m_settings, resultDuplicated, this); duplicatedGamepad = false; connect(damncontroller, &GameController::requestWait, eventWorker, &SDLEventReader::haltServices); SDL_Joystick *sdlStick = SDL_GameControllerGetJoystick(controller); joystickID = SDL_JoystickInstanceID(sdlStick); m_joysticks->insert(joystickID, damncontroller); trackcontrollers.insert(joystickID, damncontroller); emit deviceUpdated(i, damncontroller); } } } // Make sure to decrement reference count SDL_JoystickClose(joystick); } } void InputDaemon::removeDevice(InputDevice *device) { if (device != nullptr) { SDL_JoystickID deviceID = device->getSDLJoystickID(); m_joysticks->remove(deviceID); getTrackjoysticksLocal().remove(deviceID); trackcontrollers.remove(deviceID); refreshIndexes(); emit deviceRemoved(deviceID); } } void InputDaemon::refreshIndexes() { for (int i = 0; i < SDL_NumJoysticks(); i++) // for (int i = 0; i < 1; i++) { SDL_Joystick *joystick = SDL_JoystickOpen(i); // SDL_Joystick *joystick = xbox360; SDL_JoystickID joystickID = SDL_JoystickInstanceID(joystick); SDL_JoystickClose(joystick); // Make sure to decrement reference count InputDevice *tempdevice = m_joysticks->value(joystickID); if (tempdevice != nullptr) tempdevice->setIndex(i); } } void InputDaemon::addInputDevice(int index, QMap &uniques, int &counterUniques, bool &duplicatedGamepad) { #ifdef USE_NEW_ADD // Check if device is considered a Game Controller at the start. if (SDL_IsGameController(index)) { SDL_GameController *controller = SDL_GameControllerOpen(index); if (controller != nullptr) { SDL_Joystick *sdlStick = SDL_GameControllerGetJoystick(controller); SDL_JoystickID tempJoystickID = SDL_JoystickInstanceID(sdlStick); // Check if device has already been grabbed. if (!m_joysticks->contains(tempJoystickID)) { m_settings->getLock()->lock(); m_settings->beginGroup("Mappings"); QString temp = QString(); SDL_JoystickGUID tempGUID = SDL_JoystickGetGUID(sdlStick); char guidString[65] = {'0'}; SDL_JoystickGetGUIDString(tempGUID, guidString, sizeof(guidString)); temp = QString(guidString); bool disableGameController = m_settings->value(QString("%1Disable").arg(temp), false).toBool(); m_settings->endGroup(); m_settings->getLock()->unlock(); // Check if user has designated device Joystick mode. if (!disableGameController) { GameController *damncontroller = new GameController(controller, index, m_settings, this); connect(damncontroller, &GameController::requestWait, eventWorker, &SDLEventReader::haltServices); m_joysticks->insert(tempJoystickID, damncontroller); trackcontrollers.insert(tempJoystickID, damncontroller); qInfo() << QString("New game controller found - #%1 [%2]".arg(index + 1).arg( QTime::currentTime().toString("hh:mm:ss.zzz"))); emit deviceAdded(damncontroller); } else { // Check if joystick is considered connected. Joystick *joystick = openJoystickDevice(index); if (joystick != nullptr) { qInfo() << QString("New joystick found - #%1 [%2]".arg(index + 1).arg( QTime::currentTime().toString("hh:mm:ss.zzz"))); emit deviceAdded(joystick); } } } else { // Make sure to decrement reference count SDL_GameControllerClose(controller); } } } else { Joystick *joystick = openJoystickDevice(index); if (joystick != nullptr) { Logger::LogInfo( QString("New joystick found - #%1 [%2]").arg(index + 1).arg(QTime::currentTime().toString("hh:mm:ss.zzz"))); emit deviceAdded(joystick); } } #else SDL_GameController *controller = SDL_GameControllerOpen(index); SDL_Joystick *joystick = SDL_JoystickOpen(index); // SDL_Joystick *joystick = xbox360; // SDL_GameController *controller = SDL_GameControllerFromInstanceID(xbox360->instance_id); if (joystick != nullptr) { SDL_JoystickID tempJoystickID_local = SDL_JoystickInstanceID(joystick); if (!m_joysticks->contains(tempJoystickID_local)) { m_settings->getLock()->lock(); m_settings->beginGroup("Mappings"); // QString temp = QString(); // SDL_JoystickGUID tempGUID = SDL_JoystickGetGUID(joystick); // char guidString[65] = {'0'}; // SDL_JoystickGetGUIDString(tempGUID, guidString, sizeof(guidString)); // temp = QString(guidString); // bool disableGameController = m_settings->value(QString("%1Disable").arg(temp), false).toBool(); QString guidText = QString(); SDL_JoystickGUID tempGUID = SDL_JoystickGetGUID(joystick); char guidString[65] = {'0'}; SDL_JoystickGetGUIDString(tempGUID, guidString, sizeof(guidString)); guidText = QString(guidString); QString vendor = QString(); if (controller != nullptr) { Uint16 tempVendor = SDL_GameControllerGetVendor(controller); char buffer[50]; sprintf(buffer, "%u", tempVendor); vendor = QString(buffer); } QString productID = QString(); if (controller != nullptr) { Uint16 tempProduct = SDL_GameControllerGetProduct(controller); char buffer[50]; sprintf(buffer, "%u", tempProduct); productID = QString(buffer); } if (uniques.contains(guidText)) { productID = getJoyInfo(SDL_GameControllerGetProduct(controller) + ++uniques[guidText]); duplicatedGamepad = true; uniques.insert(guidText, uniques[guidText]); } else { uniques.insert(guidText, counterUniques); } convertMappingsToUnique(m_settings, guidText, guidText + vendor + productID); int resultDuplicated = 0; if (duplicatedGamepad) resultDuplicated = uniques[guidText]; bool disableGameController = m_settings->value(QString("%1Disable").arg(guidText + vendor + productID), false).toBool(); if (SDL_IsGameController(index) && !disableGameController) { // Make sure to decrement reference count SDL_JoystickClose(joystick); SDL_GameController *controller = SDL_GameControllerOpen(index); if (controller != nullptr) { SDL_Joystick *sdlStick = SDL_GameControllerGetJoystick(controller); SDL_JoystickID tempJoystickID_local_2 = SDL_JoystickInstanceID(sdlStick); if (!m_joysticks->contains(tempJoystickID_local_2)) { GameController *damncontroller = new GameController(controller, index, m_settings, resultDuplicated, this); connect(damncontroller, &GameController::requestWait, eventWorker, &SDLEventReader::haltServices); m_joysticks->insert(tempJoystickID_local_2, damncontroller); trackcontrollers.insert(tempJoystickID_local_2, damncontroller); m_settings->endGroup(); m_settings->getLock()->unlock(); emit deviceAdded(damncontroller); } duplicatedGamepad = false; } else { m_settings->endGroup(); m_settings->getLock()->unlock(); } } else { Joystick *curJoystick = new Joystick(joystick, index, m_settings, this); m_joysticks->insert(tempJoystickID_local, curJoystick); getTrackjoysticksLocal().insert(tempJoystickID_local, curJoystick); m_settings->endGroup(); m_settings->getLock()->unlock(); emit deviceAdded(curJoystick); } } else { // Make sure to decrement reference count SDL_JoystickClose(joystick); } } #endif } Joystick *InputDaemon::openJoystickDevice(int index) { // Check if joystick is considered connected. SDL_Joystick *joystick = SDL_JoystickOpen(index); // SDL_Joystick* joystick = xbox360; Joystick *curJoystick = nullptr; if (joystick != nullptr) { SDL_JoystickID tempJoystickID = SDL_JoystickInstanceID(joystick); curJoystick = new Joystick(joystick, index, m_settings, this); m_joysticks->insert(tempJoystickID, curJoystick); getTrackjoysticksLocal().insert(tempJoystickID, curJoystick); } return curJoystick; } InputDeviceBitArrayStatus * InputDaemon::createOrGrabBitStatusEntry(QHash *statusHash, InputDevice *device, bool readCurrent) { InputDeviceBitArrayStatus *bitArrayStatus = nullptr; if (!statusHash->contains(device)) { bitArrayStatus = new InputDeviceBitArrayStatus(device, readCurrent, this); statusHash->insert(device, bitArrayStatus); } else { bitArrayStatus = statusHash->value(device); } return bitArrayStatus; } /** * @brief Fetches events from SDL event queue, filters them and * updates InputDeviceBitArrayStatus. */ void InputDaemon::firstInputPass(QQueue *sdlEventQueue) { SDL_Event event; while (SDL_PollEvent(&event) > 0) { if (Logger::isDebugEnabled()) { const QMap STRING_MAP = { {SDL_JOYBUTTONDOWN, "SDL_JOYBUTTONDOWN"}, {SDL_JOYBUTTONUP, "SDL_JOYBUTTONUP"}, {SDL_JOYAXISMOTION, "SDL_JOYAXISMOTION"}, {SDL_JOYHATMOTION, "SDL_JOYHATMOTION"}, {SDL_CONTROLLERAXISMOTION, "SDL_CONTROLLERAXISMOTION"}, {SDL_CONTROLLERBUTTONDOWN, "SDL_CONTROLLERBUTTONDOWN"}, {SDL_CONTROLLERBUTTONUP, "SDL_CONTROLLERBUTTONUP"}, {SDL_JOYDEVICEREMOVED, "SDL_JOYDEVICEREMOVED"}, {SDL_JOYDEVICEADDED, "SDL_JOYDEVICEADDED"}, {SDL_CONTROLLERDEVICEREMOVED, "SDL_CONTROLLERDEVICEREMOVED"}, {SDL_CONTROLLERDEVICEADDED, "SDL_CONTROLLERDEVICEADDED"}, #if SDL_VERSION_ATLEAST(2, 0, 14) {SDL_CONTROLLERSENSORUPDATE, "SDL_CONTROLLERSENSORUPDATE"}, {SDL_CONTROLLERTOUCHPADDOWN, "SDL_CONTROLLERTOUCHPADDOWN"}, {SDL_CONTROLLERTOUCHPADMOTION, "SDL_CONTROLLERTOUCHPADMOTION"}, {SDL_CONTROLLERTOUCHPADUP, "SDL_CONTROLLERTOUCHPADUP"} #endif }; QString type; if (STRING_MAP.contains(event.type)) type = STRING_MAP[event.type]; else type = QString().number(event.type); DEBUG() << "Processing event: " << type << " From joystick with instance id: " << (int)event.jbutton.which << " Got button with id: " << (int)event.jbutton.button << " is one of the GameControllers: " << (trackcontrollers.contains(event.jbutton.which) ? "true" : "false") << " is one of the joysticks:" << (getTrackjoysticksLocal().contains(event.jbutton.which) ? "true" : "false"); } switch (event.type) { case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: { InputDevice *joy = getTrackjoysticksLocal().value(event.jbutton.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoyButton *button = set->getJoyButton(event.jbutton.button); if (button != nullptr) { InputDeviceBitArrayStatus *pending = createOrGrabBitStatusEntry(&pendingEventValues, joy); pending->changeButtonStatus(event.jbutton.button, event.type == SDL_JOYBUTTONDOWN ? true : false); sdlEventQueue->append(event); } } else { sdlEventQueue->append(event); } break; } case SDL_JOYAXISMOTION: { InputDevice *joy = getTrackjoysticksLocal().value(event.jaxis.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoyAxis *axis = set->getJoyAxis(event.jaxis.axis); if (axis != nullptr) { InputDeviceBitArrayStatus *temp = createOrGrabBitStatusEntry(&releaseEventsGenerated, joy, false); temp->changeAxesStatus(event.jaxis.axis, event.jaxis.axis == 0); InputDeviceBitArrayStatus *pending = createOrGrabBitStatusEntry(&pendingEventValues, joy); pending->changeAxesStatus(event.jaxis.axis, !axis->inDeadZone(event.jaxis.value)); sdlEventQueue->append(event); } } else { sdlEventQueue->append(event); } break; } case SDL_JOYHATMOTION: { InputDevice *joy = getTrackjoysticksLocal().value(event.jhat.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoyDPad *dpad = set->getJoyDPad(event.jhat.hat); if (dpad != nullptr) { InputDeviceBitArrayStatus *pending = createOrGrabBitStatusEntry(&pendingEventValues, joy); pending->changeHatStatus(event.jhat.hat, (event.jhat.value != 0) ? true : false); sdlEventQueue->append(event); } } else { sdlEventQueue->append(event); } break; } case SDL_CONTROLLERAXISMOTION: { InputDevice *joy = trackcontrollers.value(event.caxis.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoyAxis *axis = set->getJoyAxis(event.caxis.axis); if (axis != nullptr) { InputDeviceBitArrayStatus *temp = createOrGrabBitStatusEntry(&releaseEventsGenerated, joy, false); if ((event.caxis.axis != SDL_CONTROLLER_AXIS_TRIGGERLEFT) && (event.caxis.axis != SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) { temp->changeAxesStatus(event.caxis.axis, event.caxis.value == 0); } else { temp->changeAxesStatus(event.caxis.axis, event.caxis.value == GlobalVariables::InputDaemon::GAMECONTROLLERTRIGGERRELEASE); } InputDeviceBitArrayStatus *pending = createOrGrabBitStatusEntry(&pendingEventValues, joy); pending->changeAxesStatus(event.caxis.axis, !axis->inDeadZone(event.caxis.value)); sdlEventQueue->append(event); } } break; } #if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_CONTROLLERSENSORUPDATE: { InputDevice *joy = trackcontrollers.value(event.caxis.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoySensorType sensor_type; if (event.csensor.sensor == SDL_SENSOR_ACCEL) sensor_type = ACCELEROMETER; else if (event.csensor.sensor == SDL_SENSOR_GYRO) sensor_type = GYROSCOPE; else qWarning() << "Unknown sensor type: " << event.csensor.sensor; JoySensor *sensor = nullptr; if (sensor_type == ACCELEROMETER || sensor_type == GYROSCOPE) sensor = set->getSensor(sensor_type); if (sensor != nullptr) { InputDeviceBitArrayStatus *temp = createOrGrabBitStatusEntry(&releaseEventsGenerated, joy, false); temp->changeSensorStatus(sensor_type, event.csensor.sensor == 0); InputDeviceBitArrayStatus *pending = createOrGrabBitStatusEntry(&pendingEventValues, joy); pending->changeSensorStatus(sensor_type, !sensor->inDeadZone(event.csensor.data)); sdlEventQueue->append(event); } } else { sdlEventQueue->append(event); } break; } #endif case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP: { InputDevice *joy = trackcontrollers.value(event.cbutton.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoyButton *button = set->getJoyButton(event.cbutton.button); if (button != nullptr) { InputDeviceBitArrayStatus *pending = createOrGrabBitStatusEntry(&pendingEventValues, joy); pending->changeButtonStatus(event.cbutton.button, event.type == SDL_CONTROLLERBUTTONDOWN ? true : false); sdlEventQueue->append(event); } } break; } case SDL_JOYDEVICEREMOVED: case SDL_JOYDEVICEADDED: case SDL_CONTROLLERDEVICEADDED: case SDL_CONTROLLERDEVICEREMOVED: { sdlEventQueue->append(event); break; } case SDL_QUIT: { sdlEventQueue->append(event); break; } default: { break; } } } } /** * @brief Postprocesses fetched raw events. */ void InputDaemon::modifyUnplugEvents(QQueue *sdlEventQueue) { QHashIterator genIter(getReleaseEventsGeneratedLocal()); while (genIter.hasNext()) { genIter.next(); InputDevice *device = genIter.key(); InputDeviceBitArrayStatus *generatedTemp = genIter.value(); QBitArray tempBitArray = generatedTemp->generateFinalBitArray(); int bitArraySize = tempBitArray.size(); qDebug() << "Raw array: " << tempBitArray << " array size: " << bitArraySize; if ((bitArraySize > 0) && (tempBitArray.count(true) == device->getNumberAxes())) { if (getPendingEventValuesLocal().contains(device)) { InputDeviceBitArrayStatus *pendingTemp = getPendingEventValuesLocal().value(device); QBitArray pendingBitArray = pendingTemp->generateFinalBitArray(); QBitArray unplugBitArray = createUnplugEventBitArray(device); int pendingBitArraySize = pendingBitArray.size(); if ((bitArraySize == pendingBitArraySize) && (pendingBitArray == unplugBitArray)) { QQueue tempQueue; while (!sdlEventQueue->isEmpty()) { SDL_Event event = sdlEventQueue->dequeue(); switch (event.type) { case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: { tempQueue.enqueue(event); break; } case SDL_JOYAXISMOTION: { if (event.jaxis.which != device->getSDLJoystickID()) { tempQueue.enqueue(event); } else { InputDevice *joy = getTrackjoysticksLocal().value(event.jaxis.which); if (joy != nullptr) { JoyAxis *axis = joy->getActiveSetJoystick()->getJoyAxis(event.jaxis.axis); if (axis != nullptr) { if (axis->getThrottle() != static_cast(JoyAxis::NormalThrottle)) { event.jaxis.value = axis->getProperReleaseValue(); } } } tempQueue.enqueue(event); } break; } case SDL_JOYHATMOTION: { tempQueue.enqueue(event); break; } case SDL_CONTROLLERAXISMOTION: { if (event.caxis.which != device->getSDLJoystickID()) { tempQueue.enqueue(event); } else { InputDevice *joy = trackcontrollers.value(event.caxis.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoyAxis *axis = set->getJoyAxis(event.caxis.axis); if (axis != nullptr) { if ((event.caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT) || (event.caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) { event.caxis.value = axis->getProperReleaseValue(); } } } tempQueue.enqueue(event); } break; } #if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_CONTROLLERSENSORUPDATE: { tempQueue.enqueue(event); break; } #endif case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP: { tempQueue.enqueue(event); break; } case SDL_JOYDEVICEREMOVED: case SDL_JOYDEVICEADDED: case SDL_CONTROLLERDEVICEREMOVED: case SDL_CONTROLLERDEVICEADDED: { tempQueue.enqueue(event); break; } default: { tempQueue.enqueue(event); } } } sdlEventQueue->swap(tempQueue); } } } } } QBitArray InputDaemon::createUnplugEventBitArray(InputDevice *device) { InputDeviceBitArrayStatus tempStatus(device, false, this); for (int i = 0; i < device->getNumberRawAxes(); i++) { JoyAxis *axis = device->getActiveSetJoystick()->getJoyAxis(i); if ((axis != nullptr) && (axis->getThrottle() != static_cast(JoyAxis::NormalThrottle))) tempStatus.changeAxesStatus(i, true); } QBitArray unplugBitArray = tempStatus.generateFinalBitArray(); return unplugBitArray; } /** * @brief Dispatches postprocessed SDL events to the input objects like * JoyAxis or JoyButton and activates them at the end. */ void InputDaemon::secondInputPass(QQueue *sdlEventQueue) { QMap uniques = QMap(); int counterUniques = 1; bool duplicatedGamepad = false; QHash activeDevices; while (!sdlEventQueue->isEmpty()) { SDL_Event event = sdlEventQueue->dequeue(); switch (event.type) { case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: { InputDevice *joy = getTrackjoysticksLocal().value(event.jbutton.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoyButton *button = set->getJoyButton(event.jbutton.button); if (button != nullptr) { button->queuePendingEvent(event.type == SDL_JOYBUTTONDOWN ? true : false); if (!activeDevices.contains(event.jbutton.which)) activeDevices.insert(event.jbutton.which, joy); } } else if (trackcontrollers.contains(event.jbutton.which)) { GameController *gamepad = trackcontrollers.value(event.jbutton.which); gamepad->rawButtonEvent(event.jbutton.button, event.type == SDL_JOYBUTTONDOWN ? true : false); } break; } case SDL_JOYAXISMOTION: { InputDevice *joy = getTrackjoysticksLocal().value(event.jaxis.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoyAxis *axis = set->getJoyAxis(event.jaxis.axis); if (axis != nullptr) { axis->queuePendingEvent(event.jaxis.value); if (!activeDevices.contains(event.jaxis.which)) activeDevices.insert(event.jaxis.which, joy); } joy->rawAxisEvent(event.jaxis.which, event.jaxis.value); } else if (trackcontrollers.contains(event.jaxis.which)) { GameController *gamepad = trackcontrollers.value(event.jaxis.which); gamepad->rawAxisEvent(event.jaxis.axis, event.jaxis.value); } break; } case SDL_JOYHATMOTION: { InputDevice *joy = getTrackjoysticksLocal().value(event.jhat.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoyDPad *dpad = set->getJoyDPad(event.jhat.hat); if (dpad != nullptr) { dpad->joyEvent(event.jhat.value); if (!activeDevices.contains(event.jhat.which)) activeDevices.insert(event.jhat.which, joy); } } else if (trackcontrollers.contains(event.jhat.which)) { GameController *gamepad = trackcontrollers.value(event.jaxis.which); gamepad->rawDPadEvent(event.jhat.hat, event.jhat.value); } break; } case SDL_CONTROLLERAXISMOTION: { InputDevice *joy = trackcontrollers.value(event.caxis.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoyAxis *axis = set->getJoyAxis(event.caxis.axis); if (axis != nullptr) { axis->queuePendingEvent(event.caxis.value); if (!activeDevices.contains(event.caxis.which)) activeDevices.insert(event.caxis.which, joy); } } break; } #if SDL_VERSION_ATLEAST(2, 0, 14) case SDL_CONTROLLERSENSORUPDATE: { InputDevice *joy = trackcontrollers.value(event.csensor.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoySensor *sensor = nullptr; if (event.csensor.sensor == SDL_SENSOR_ACCEL) sensor = set->getSensor(ACCELEROMETER); else if (event.csensor.sensor == SDL_SENSOR_GYRO) sensor = set->getSensor(GYROSCOPE); else Q_ASSERT(false); if (sensor != nullptr) { sensor->queuePendingEvent(event.csensor.data); if (!activeDevices.contains(event.csensor.which)) activeDevices.insert(event.csensor.which, joy); } } break; } #endif case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP: { InputDevice *joy = trackcontrollers.value(event.cbutton.which); if (joy != nullptr) { SetJoystick *set = joy->getActiveSetJoystick(); JoyButton *button = set->getJoyButton(event.cbutton.button); if (button != nullptr) { button->queuePendingEvent(event.type == SDL_CONTROLLERBUTTONDOWN ? true : false); if (!activeDevices.contains(event.cbutton.which)) activeDevices.insert(event.cbutton.which, joy); } } break; } case SDL_JOYDEVICEREMOVED: case SDL_CONTROLLERDEVICEREMOVED: { InputDevice *device = m_joysticks->value(event.jdevice.which); if (device != nullptr) { qInfo() << QString("Removing joystick #%1 [%2]") .arg(device->getRealJoyNumber()) .arg(QTime::currentTime().toString("hh:mm:ss.zzz")); removeDevice(device); } break; } case SDL_JOYDEVICEADDED: case SDL_CONTROLLERDEVICEADDED: { addInputDevice(event.jdevice.which, uniques, counterUniques, duplicatedGamepad); break; } case SDL_QUIT: { stopped = true; break; } default: break; } // Active possible queued events. QHashIterator activeDevIter(activeDevices); while (activeDevIter.hasNext()) { InputDevice *tempDevice = activeDevIter.next().value(); tempDevice->activatePossibleControlStickEvents(); tempDevice->activatePossibleAxisEvents(); tempDevice->activatePossibleSensorEvents(); tempDevice->activatePossibleDPadEvents(); tempDevice->activatePossibleVDPadEvents(); tempDevice->activatePossibleButtonEvents(); } if (JoyButton::shouldInvokeMouseEvents(JoyButton::getPendingMouseButtons(), JoyButton::getStaticMouseEventTimer(), JoyButton::getTestOldMouseTime())) JoyButton::invokeMouseEvents( JoyButton::getMouseHelper()); // Do not wait for next event loop run. Execute immediately. } } void InputDaemon::clearBitArrayStatusInstances() { QHashIterator genIter(releaseEventsGenerated); while (genIter.hasNext()) { InputDeviceBitArrayStatus *temp = genIter.next().value(); if (temp != nullptr) { temp->deleteLater(); temp = nullptr; } } getReleaseEventsGeneratedLocal().clear(); QHashIterator pendIter(pendingEventValues); while (pendIter.hasNext()) { InputDeviceBitArrayStatus *temp = pendIter.next().value(); if (temp != nullptr) { temp->deleteLater(); temp = nullptr; } } getPendingEventValuesLocal().clear(); } void InputDaemon::resetActiveButtonMouseDistances() { pollResetTimer.stop(); JoyButton::resetActiveButtonMouseDistances(JoyButton::getMouseHelper()); } void InputDaemon::updatePollResetRate(int tempPollRate) { Q_UNUSED(tempPollRate); bool wasActive = pollResetTimer.isActive(); pollResetTimer.stop(); pollResetTimer.setInterval( qMax(GlobalVariables::JoyButton::mouseRefreshRate, GlobalVariables::JoyButton::gamepadRefreshRate) + 1); if (wasActive) pollResetTimer.start(); } void InputDaemon::convertMappingsToUnique(QSettings *sett, QString guidString, QString uniqueIdString) { if (sett->contains(QString("%1Disable").arg(guidString))) { sett->setValue(QString("%1Disable").arg(uniqueIdString), sett->value(QString("%1Disable").arg(guidString))); sett->remove(QString("%1Disable").arg(guidString)); } if (sett->contains(guidString)) { QStringList gg = sett->value(guidString).toString().split(","); qDebug() << "Convert guidString to uniqueString 1): " << gg; gg.removeFirst(); qDebug() << "Convert guidString to uniqueString 2): " << gg; gg.prepend(uniqueIdString); qDebug() << "Convert guidString to uniqueString 3): " << gg; qDebug() << "Joined uniqueMapping: " << gg.join(","); sett->setValue(uniqueIdString, gg.join(",")); sett->remove(guidString); } } QHash &InputDaemon::getTrackjoysticksLocal() { return trackjoysticks; } QHash &InputDaemon::getReleaseEventsGeneratedLocal() { return releaseEventsGenerated; } QHash &InputDaemon::getPendingEventValuesLocal() { return pendingEventValues; } AntiMicroX-antimicrox-b300273/src/inputdaemon.h000066400000000000000000000076511471077622000214460ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef INPUTDAEMONTHREAD_H #define INPUTDAEMONTHREAD_H #include "gamecontroller/gamecontroller.h" //#include "fakeclasses/xbox360wireless.h" #include class InputDevice; class AntiMicroSettings; class InputDeviceBitArrayStatus; class Joystick; class GameController; class SDLEventReader; class QThread; /** * @brief Fetches hardware events from SDL and dispatch them to * input objects like JoyAxis or JoyButton. * Runs in a separate thread. */ class InputDaemon : public QObject { Q_OBJECT public: explicit InputDaemon(QMap *joysticks, AntiMicroSettings *settings, bool graphical = true, QObject *parent = 0); ~InputDaemon(); protected: InputDeviceBitArrayStatus *createOrGrabBitStatusEntry(QHash *statusHash, InputDevice *device, bool readCurrent = true); QString getJoyInfo(SDL_JoystickGUID sdlvalue); QString getJoyInfo(Uint16 sdlvalue); void firstInputPass(QQueue *sdlEventQueue); void secondInputPass(QQueue *sdlEventQueue); void modifyUnplugEvents(QQueue *sdlEventQueue); QBitArray createUnplugEventBitArray(InputDevice *device); Joystick *openJoystickDevice(int index); void clearBitArrayStatusInstances(); void convertMappingsToUnique(QSettings *sett, QString guidString, QString uniqueIdString); signals: void joystickRefreshed(InputDevice *joystick); void joysticksRefreshed(QMap *joysticks); void complete(InputDevice *joystick); void complete(); void deviceUpdated(int index, InputDevice *device); void deviceRemoved(SDL_JoystickID deviceID); void deviceAdded(InputDevice *device); public slots: void run(); void quit(); void refresh(); void refreshJoystick(InputDevice *joystick); void refreshJoysticks(); void startWorker(); void refreshMapping(QString mapping, InputDevice *device); void removeDevice(InputDevice *device); void addInputDevice(int index, QMap &uniques, int &counterUniques, bool &duplicatedGamepad); void refreshIndexes(); private slots: void stop(); void resetActiveButtonMouseDistances(); void updatePollResetRate(int tempPollRate); private: QHash &getTrackjoysticksLocal(); QHash &getReleaseEventsGeneratedLocal(); QHash &getPendingEventValuesLocal(); QMap *m_joysticks; QHash trackjoysticks; QHash trackcontrollers; QHash releaseEventsGenerated; QHash pendingEventValues; bool stopped; bool m_graphical; SDLEventReader *eventWorker; QThread *sdlWorkerThread; AntiMicroSettings *m_settings; QTimer pollResetTimer; // SDL_Joystick* xbox360; }; #endif // INPUTDAEMONTHREAD_H AntiMicroX-antimicrox-b300273/src/inputdevice.cpp000066400000000000000000001775371471077622000220100ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "inputdevice.h" #include "antimicrosettings.h" #include "common.h" #include "globalvariables.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joybuttontypes/joydpadbutton.h" #include "joybuttontypes/joysensorbutton.h" #include "joycontrolstick.h" #include "joydpad.h" #include "joysensor.h" #include "vdpad.h" #include #include #include #include InputDevice::InputDevice(SDL_Joystick *joystick, int deviceIndex, AntiMicroSettings *settings, QObject *parent) : QObject(parent) , m_calibrations(this) { buttonDownCount = 0; joyNumber = deviceIndex; active_set = 0; joystickID = 0; keyPressTime = 0; m_joyhandle = joystick; deviceEdited = false; keyRepeatEnabled = false; keyRepeatDelay = 0; keyRepeatRate = 0; rawAxisDeadZone = GlobalVariables::InputDevice::RAISEDDEADZONE; m_settings = settings; } InputDevice::~InputDevice() {} int InputDevice::getJoyNumber() { return joyNumber; } int InputDevice::getRealJoyNumber() { int joynumber = getJoyNumber(); return joynumber + 1; } void InputDevice::reset() { resetButtonDownCount(); deviceEdited = false; profileName = ""; for (int i = 0; i < GlobalVariables::InputDevice::NUMBER_JOYSETS; i++) { SetJoystick *set = getJoystick_sets().value(i); set->reset(); } } /** * @brief Obtain current joystick element values, create new SetJoystick objects, * and then transfer most recent joystick element values to new * current set. */ void InputDevice::transferReset() { // Grab current states for all elements in old set SetJoystick *current_set = getJoystick_sets().value(active_set); for (int i = 0; i < current_set->getNumberButtons(); i++) { JoyButton *button = current_set->getJoyButton(i); getButtonstatesLocal().append(button->getButtonState()); } for (int i = 0; i < current_set->getNumberAxes(); i++) { JoyAxis *axis = current_set->getJoyAxis(i); getAxesstatesLocal().append(axis->getCurrentRawValue()); } for (int i = 0; i < current_set->getNumberHats(); i++) { JoyDPad *dpad = current_set->getJoyDPad(i); getDpadstatesLocal().append(dpad->getCurrentDirection()); } reset(); } void InputDevice::reInitButtons() { SetJoystick *current_set = getJoystick_sets().value(active_set); for (int i = 0; i < current_set->getNumberButtons(); i++) { bool value = getButtonstatesLocal().at(i); JoyButton *button = current_set->getJoyButton(i); button->queuePendingEvent(value); } for (int i = 0; i < current_set->getNumberAxes(); i++) { int value = getAxesstatesLocal().at(i); JoyAxis *axis = current_set->getJoyAxis(i); axis->queuePendingEvent(value); } for (int i = 0; i < current_set->getNumberHats(); i++) { int value = getDpadstatesLocal().at(i); JoyDPad *dpad = current_set->getJoyDPad(i); dpad->queuePendingEvent(value); } activatePossibleControlStickEvents(); activatePossibleAxisEvents(); activatePossibleDPadEvents(); activatePossibleVDPadEvents(); activatePossibleButtonEvents(); buttonstates.clear(); axesstates.clear(); dpadstates.clear(); } void InputDevice::setActiveSetNumber(int index) { VERBOSE() << "Change active set number from: " << active_set << " to: " << index << " for device with Index: " << getRealJoyNumber(); if (((index >= 0) && (index < GlobalVariables::InputDevice::NUMBER_JOYSETS)) && (index != active_set)) { QList buttonstates; QList axesstates; QList dpadstates; QList stickstates; QList vdpadstates; // Grab current states for all elements in old set SetJoystick *current_set = getJoystick_sets().value(active_set); SetJoystick *old_set = current_set; SetJoystick *tempSet = getJoystick_sets().value(index); for (int i = 0; i < current_set->getNumberButtons(); i++) { JoyButton *button = current_set->getJoyButton(i); buttonstates.append(button->getButtonState()); tempSet->getJoyButton(i)->copyLastMouseDistanceFromDeadZone(button); tempSet->getJoyButton(i)->copyLastAccelerationDistance(button); tempSet->getJoyButton(i)->setUpdateInitAccel(false); } for (int i = 0; i < current_set->getNumberAxes(); i++) { JoyAxis *axis = current_set->getJoyAxis(i); axesstates.append(axis->getCurrentRawValue()); tempSet->getJoyAxis(i)->copyRawValues(axis); tempSet->getJoyAxis(i)->copyThrottledValues(axis); JoyAxisButton *button = tempSet->getJoyAxis(i)->getAxisButtonByValue(axis->getCurrentRawValue()); if (button != nullptr) { button->setUpdateInitAccel(false); } } for (int i = 0; i < current_set->getNumberHats(); i++) { JoyDPad *dpad = current_set->getJoyDPad(i); dpadstates.append(dpad->getCurrentDirection()); JoyDPadButton::JoyDPadDirections tempDir = static_cast(dpad->getCurrentDirection()); tempSet->getJoyDPad(i)->setDirButtonsUpdateInitAccel(tempDir, false); tempSet->getJoyDPad(i)->copyLastDistanceValues(dpad); } for (int i = 0; i < current_set->getNumberSticks(); i++) { // Last distances for elements are taken from associated axes. // Copying is not required here. JoyControlStick *stick = current_set->getJoyStick(i); stickstates.append(stick->getCurrentDirection()); tempSet->getJoyStick(i)->setDirButtonsUpdateInitAccel(stick->getCurrentDirection(), false); } for (int i = 0; i < current_set->getNumberVDPads(); i++) { JoyDPad *dpad = current_set->getVDPad(i); vdpadstates.append(dpad->getCurrentDirection()); JoyDPadButton::JoyDPadDirections tempDir = static_cast(dpad->getCurrentDirection()); tempSet->getVDPad(i)->setDirButtonsUpdateInitAccel(tempDir, false); tempSet->getVDPad(i)->copyLastDistanceValues(dpad); } // Release all current pressed elements and change set number getJoystick_sets().value(active_set)->release(); active_set = index; // Activate all buttons in the switched set current_set = getJoystick_sets().value(active_set); for (int i = 0; i < current_set->getNumberSticks(); i++) { JoyControlStick::JoyStickDirections value = stickstates.at(i); QList buttonList; QList oldButtonList; JoyControlStick *stick = current_set->getJoyStick(i); JoyControlStick *oldStick = old_set->getJoyStick(i); if ((stick->getJoyMode() == JoyControlStick::StandardMode) && value) { switch (value) { case JoyControlStick::StickRightUp: { buttonList.append(stick->getDirectionButton(JoyControlStick::StickUp)); buttonList.append(stick->getDirectionButton(JoyControlStick::StickRight)); oldButtonList.append(oldStick->getDirectionButton(JoyControlStick::StickUp)); oldButtonList.append(oldStick->getDirectionButton(JoyControlStick::StickRight)); break; } case JoyControlStick::StickRightDown: { buttonList.append(stick->getDirectionButton(JoyControlStick::StickRight)); buttonList.append(stick->getDirectionButton(JoyControlStick::StickDown)); oldButtonList.append(oldStick->getDirectionButton(JoyControlStick::StickRight)); oldButtonList.append(oldStick->getDirectionButton(JoyControlStick::StickDown)); break; } case JoyControlStick::StickLeftDown: { buttonList.append(stick->getDirectionButton(JoyControlStick::StickDown)); buttonList.append(stick->getDirectionButton(JoyControlStick::StickLeft)); oldButtonList.append(oldStick->getDirectionButton(JoyControlStick::StickDown)); oldButtonList.append(oldStick->getDirectionButton(JoyControlStick::StickLeft)); break; } case JoyControlStick::StickLeftUp: { buttonList.append(stick->getDirectionButton(JoyControlStick::StickLeft)); buttonList.append(stick->getDirectionButton(JoyControlStick::StickUp)); oldButtonList.append(oldStick->getDirectionButton(JoyControlStick::StickLeft)); oldButtonList.append(oldStick->getDirectionButton(JoyControlStick::StickUp)); break; } default: { buttonList.append(stick->getDirectionButton(value)); oldButtonList.append(oldStick->getDirectionButton(value)); } } } else if (value) { buttonList.append(stick->getDirectionButton(value)); oldButtonList.append(oldStick->getDirectionButton(value)); } QHashIterator iter(*stick->getButtons()); while (iter.hasNext()) { JoyControlStickButton *tempButton = iter.next().value(); if (!buttonList.contains(tempButton)) { tempButton->setWhileHeldStatus(false); } } for (int j = 0; j < buttonList.size(); j++) { JoyControlStickButton *button = buttonList.at(j); JoyControlStickButton *oldButton = oldButtonList.at(j); if ((button != nullptr) && (oldButton != nullptr)) { if (button->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) { if ((oldButton->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && oldButton->getWhileHeldStatus()) { // Button from old set involved in a while held set // change. Carry over to new set button to ensure // set changes are done in the proper order. button->setWhileHeldStatus(true); } else if (!button->getWhileHeldStatus()) { // Ensure that set change events are performed if needed. // tempignore = false; } } } } } // Activate all dpad buttons in the switched set for (int i = 0; i < current_set->getNumberVDPads(); i++) { int value = vdpadstates.at(i); JoyDPad *dpad = current_set->getVDPad(i); QList buttonList; QList oldButtonList; bool valueTrue = (value != 0); if ((dpad->getJoyMode() == JoyDPad::StandardMode) && valueTrue) { switch (value) { case JoyDPadButton::DpadRightUp: { buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadUp)); buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadRight)); oldButtonList.append(old_set->getVDPad(i)->getJoyButton(JoyDPadButton::DpadUp)); oldButtonList.append(old_set->getVDPad(i)->getJoyButton(JoyDPadButton::DpadRight)); break; } case JoyDPadButton::DpadRightDown: { buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadRight)); buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadDown)); oldButtonList.append(old_set->getVDPad(i)->getJoyButton(JoyDPadButton::DpadRight)); oldButtonList.append(old_set->getVDPad(i)->getJoyButton(JoyDPadButton::DpadDown)); break; } case JoyDPadButton::DpadLeftDown: { buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadDown)); buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadLeft)); oldButtonList.append(old_set->getVDPad(i)->getJoyButton(JoyDPadButton::DpadDown)); oldButtonList.append(old_set->getVDPad(i)->getJoyButton(JoyDPadButton::DpadLeft)); break; } case JoyDPadButton::DpadLeftUp: { buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadLeft)); buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadUp)); oldButtonList.append(old_set->getVDPad(i)->getJoyButton(JoyDPadButton::DpadLeft)); oldButtonList.append(old_set->getVDPad(i)->getJoyButton(JoyDPadButton::DpadUp)); break; } default: { buttonList.append(dpad->getJoyButton(value)); oldButtonList.append(old_set->getVDPad(i)->getJoyButton(value)); } } } else if (valueTrue) { buttonList.append(dpad->getJoyButton(value)); oldButtonList.append(old_set->getVDPad(i)->getJoyButton(value)); } QHashIterator iter(*dpad->getJoyButtons()); while (iter.hasNext()) { // Ensure that set change events are performed if needed. JoyDPadButton *button = iter.next().value(); if (!buttonList.contains(button)) { button->setWhileHeldStatus(false); } } for (int j = 0; j < buttonList.size(); j++) { JoyDPadButton *button = buttonList.at(j); JoyDPadButton *oldButton = oldButtonList.at(j); if ((button != nullptr) && (oldButton != nullptr) && (button->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && valueTrue && (oldButton->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && oldButton->getWhileHeldStatus()) { // Button from old set involved in a while held set // change. Carry over to new set button to ensure // set changes are done in the proper order. button->setWhileHeldStatus(true); } else if ((button != nullptr) && (oldButton != nullptr) && (button->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && !valueTrue) { button->setWhileHeldStatus(false); } } } for (int i = 0; i < current_set->getNumberButtons(); i++) { bool value = buttonstates.at(i); bool tempignore = false; JoyButton *button = current_set->getJoyButton(i); JoyButton *oldButton = old_set->getJoyButton(i); if (button->getChangeSetCondition() == JoyButton::SetChangeWhileHeld && value && (oldButton->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && oldButton->getWhileHeldStatus()) { // Button from old set involved in a while held set // change. Carry over to new set button to ensure // set changes are done in the proper order. button->setWhileHeldStatus(true); } else if (button->getChangeSetCondition() == JoyButton::SetChangeWhileHeld && value && !button->getWhileHeldStatus()) { // Ensure that set change events are performed if needed. tempignore = false; } else if (button->getChangeSetCondition() == JoyButton::SetChangeWhileHeld && !value) { // Ensure that set change events are performed if needed. button->setWhileHeldStatus(false); } button->queuePendingEvent(value, tempignore); } // Activate all axis buttons in the switched set for (int i = 0; i < current_set->getNumberAxes(); i++) { int value = axesstates.at(i); bool tempignore = false; JoyAxis *axis = current_set->getJoyAxis(i); JoyAxisButton *oldButton = old_set->getJoyAxis(i)->getAxisButtonByValue(value); JoyAxisButton *button = axis->getAxisButtonByValue(value); if ((button != nullptr) && (oldButton != nullptr) && (button->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && (oldButton->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && oldButton->getWhileHeldStatus()) { // Button from old set involved in a while held set // change. Carry over to new set button to ensure // set changes are done in the proper order. button->setWhileHeldStatus(true); } else if ((button != nullptr) && (oldButton != nullptr) && (button->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && !button->getWhileHeldStatus()) { // Ensure that set change events are performed if needed. tempignore = false; } else if (button == nullptr) { // Ensure that set change events are performed if needed. axis->getPAxisButton()->setWhileHeldStatus(false); axis->getNAxisButton()->setWhileHeldStatus(false); } axis->queuePendingEvent(value, tempignore, false); } // Activate all dpad buttons in the switched set for (int i = 0; i < current_set->getNumberHats(); i++) { int value = dpadstates.at(i); bool tempignore = false; JoyDPad *dpad = current_set->getJoyDPad(i); QList buttonList; QList oldButtonList; bool valueTrue = (value != 0); if ((dpad->getJoyMode() == JoyDPad::StandardMode) && valueTrue) { switch (value) { case JoyDPadButton::DpadRightUp: { buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadUp)); buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadRight)); oldButtonList.append(old_set->getJoyDPad(i)->getJoyButton(JoyDPadButton::DpadUp)); oldButtonList.append(old_set->getJoyDPad(i)->getJoyButton(JoyDPadButton::DpadRight)); break; } case JoyDPadButton::DpadRightDown: { buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadRight)); buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadDown)); oldButtonList.append(old_set->getJoyDPad(i)->getJoyButton(JoyDPadButton::DpadRight)); oldButtonList.append(old_set->getJoyDPad(i)->getJoyButton(JoyDPadButton::DpadDown)); break; } case JoyDPadButton::DpadLeftDown: { buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadDown)); buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadLeft)); oldButtonList.append(old_set->getJoyDPad(i)->getJoyButton(JoyDPadButton::DpadDown)); oldButtonList.append(old_set->getJoyDPad(i)->getJoyButton(JoyDPadButton::DpadLeft)); break; } case JoyDPadButton::DpadLeftUp: { buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadLeft)); buttonList.append(dpad->getJoyButton(JoyDPadButton::DpadUp)); oldButtonList.append(old_set->getJoyDPad(i)->getJoyButton(JoyDPadButton::DpadLeft)); oldButtonList.append(old_set->getJoyDPad(i)->getJoyButton(JoyDPadButton::DpadUp)); break; } default: { buttonList.append(dpad->getJoyButton(value)); oldButtonList.append(old_set->getJoyDPad(i)->getJoyButton(value)); } } } else if (valueTrue) { buttonList.append(dpad->getJoyButton(value)); oldButtonList.append(old_set->getJoyDPad(i)->getJoyButton(value)); } QHashIterator iter(*dpad->getJoyButtons()); while (iter.hasNext()) { // Ensure that set change events are performed if needed. JoyDPadButton *button = iter.next().value(); if (!buttonList.contains(button)) button->setWhileHeldStatus(false); } for (int j = 0; j < buttonList.size(); j++) { JoyDPadButton *button = buttonList.at(j); JoyDPadButton *oldButton = oldButtonList.at(j); if ((button != nullptr) && (oldButton != nullptr) && (button->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && valueTrue && (oldButton->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && oldButton->getWhileHeldStatus()) { // Button from old set involved in a while held set // change. Carry over to new set button to ensure // set changes are done in the proper order. button->setWhileHeldStatus(true); } else if ((button != nullptr) && (oldButton != nullptr) && (button->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && valueTrue && !button->getWhileHeldStatus()) { // Ensure that set change events are performed if needed. tempignore = false; } else if ((button != nullptr) && (oldButton != nullptr) && (button->getChangeSetCondition() == JoyButton::SetChangeWhileHeld) && !valueTrue) { button->setWhileHeldStatus(false); } } dpad->queuePendingEvent(value, tempignore); } activatePossibleControlStickEvents(); activatePossibleAxisEvents(); activatePossibleDPadEvents(); activatePossibleVDPadEvents(); activatePossibleButtonEvents(); } else { DEBUG() << "Set is not changed"; } } int InputDevice::getActiveSetNumber() { return active_set; } SetJoystick *InputDevice::getActiveSetJoystick() { return getJoystick_sets().value(active_set); } int InputDevice::getNumberButtons() { return getActiveSetJoystick()->getNumberButtons(); } int InputDevice::getNumberAxes() { return getActiveSetJoystick()->getNumberAxes(); } int InputDevice::getNumberHats() { return getActiveSetJoystick()->getNumberHats(); } int InputDevice::getNumberSticks() { return getActiveSetJoystick()->getNumberSticks(); } /** * @brief Checks if this input device has a sensor of given type * @returns True if sensor is present, false otherwise */ bool InputDevice::hasSensor(JoySensorType type) { return getActiveSetJoystick()->hasSensor(type); } int InputDevice::getNumberVDPads() { return getActiveSetJoystick()->getNumberVDPads(); } SetJoystick *InputDevice::getSetJoystick(int index) { return getJoystick_sets().value(index); } void InputDevice::propogateSetChange(int index) { emit setChangeActivated(index); } void InputDevice::changeSetButtonAssociation(int button_index, int originset, int newset, int mode) { JoyButton *button = getJoystick_sets().value(newset)->getJoyButton(button_index); JoyButton::SetChangeCondition tempmode = static_cast(mode); button->setChangeSetSelection(originset); button->setChangeSetCondition(tempmode, true); } void InputDevice::changeSetAxisButtonAssociation(int button_index, int axis_index, int originset, int newset, int mode) { JoyAxisButton *button = nullptr; if (button_index == 0) { button = getJoystick_sets().value(newset)->getJoyAxis(axis_index)->getNAxisButton(); } else if (button_index == 1) { button = getJoystick_sets().value(newset)->getJoyAxis(axis_index)->getPAxisButton(); } else { WARN() << "Invalid button_index value: " << button_index; return; } if (button != nullptr) { JoyButton::SetChangeCondition tempmode = static_cast(mode); button->setChangeSetSelection(originset); button->setChangeSetCondition(tempmode, true); } } void InputDevice::changeSetStickButtonAssociation(int button_index, int stick_index, int originset, int newset, int mode) { JoyControlStickButton *button = getJoystick_sets() .value(newset) ->getJoyStick(stick_index) ->getDirectionButton(static_cast(button_index)); JoyButton::SetChangeCondition tempmode = static_cast(mode); button->setChangeSetSelection(originset); button->setChangeSetCondition(tempmode, true); } /** * @brief Creates reverse set change button mapping for toggle and while-hold set * change mappings. */ void InputDevice::changeSetSensorButtonAssociation(JoySensorDirection direction, JoySensorType type, int originset, int newset, int mode) { JoySensorButton *button = getJoystick_sets().value(newset)->getSensor(type)->getDirectionButton(direction); JoyButton::SetChangeCondition tempmode = static_cast(mode); button->setChangeSetSelection(originset); button->setChangeSetCondition(tempmode, true); } void InputDevice::changeSetDPadButtonAssociation(int button_index, int dpad_index, int originset, int newset, int mode) { JoyDPadButton *button = getJoystick_sets().value(newset)->getJoyDPad(dpad_index)->getJoyButton(button_index); JoyButton::SetChangeCondition tempmode = static_cast(mode); button->setChangeSetSelection(originset); button->setChangeSetCondition(tempmode, true); } void InputDevice::changeSetVDPadButtonAssociation(int button_index, int dpad_index, int originset, int newset, int mode) { JoyDPadButton *button = getJoystick_sets().value(newset)->getVDPad(dpad_index)->getJoyButton(button_index); JoyButton::SetChangeCondition tempmode = static_cast(mode); button->setChangeSetSelection(originset); button->setChangeSetCondition(tempmode, true); } void InputDevice::propogateSetAxisThrottleChange(int index, int originset) { SetJoystick *currentSet = getJoystick_sets().value(originset); if (currentSet != nullptr) { JoyAxis *axis = currentSet->getJoyAxis(index); if (axis != nullptr) { int throttleSetting = axis->getThrottle(); for (auto &temp : getJoystick_sets()) { // Ignore change for set axis that initiated the change if (temp != currentSet) temp->getJoyAxis(index)->setThrottle(throttleSetting); } } } } void InputDevice::removeControlStick(int index) { for (int i = 0; i < GlobalVariables::InputDevice::NUMBER_JOYSETS; i++) { SetJoystick *currentset = getSetJoystick(i); if (currentset->getJoyStick(index)) currentset->removeControlStick(index); } } bool InputDevice::isActive() { return buttonDownCount > 0; } void InputDevice::buttonDownEvent(int setindex, int buttonindex) { Q_UNUSED(setindex); Q_UNUSED(buttonindex); bool old = isActive(); buttonDownCount += 1; if (isActive() != old) emit clicked(joyNumber); } void InputDevice::buttonUpEvent(int setindex, int buttonindex) { Q_UNUSED(setindex); Q_UNUSED(buttonindex); bool old = isActive(); buttonDownCount -= 1; if (buttonDownCount < 0) buttonDownCount = 0; if (isActive() != old) emit released(joyNumber); } void InputDevice::buttonClickEvent(int buttonindex) { emit rawButtonClick(buttonindex); } void InputDevice::buttonReleaseEvent(int buttonindex) { emit rawButtonRelease(buttonindex); } void InputDevice::axisButtonDownEvent(int setindex, int axisindex, int buttonindex) { Q_UNUSED(axisindex); buttonDownEvent(setindex, buttonindex); } void InputDevice::axisButtonUpEvent(int setindex, int axisindex, int buttonindex) { Q_UNUSED(axisindex); buttonUpEvent(setindex, buttonindex); } void InputDevice::dpadButtonClickEvent(int buttonindex) { JoyDPadButton *dpadbutton = qobject_cast(sender()); if (dpadbutton != nullptr) emit rawDPadButtonClick(dpadbutton->getDPad()->getIndex(), buttonindex); } void InputDevice::dpadButtonReleaseEvent(int buttonindex) { JoyDPadButton *dpadbutton = qobject_cast(sender()); if (dpadbutton != nullptr) emit rawDPadButtonRelease(dpadbutton->getDPad()->getIndex(), buttonindex); } void InputDevice::dpadButtonDownEvent(int setindex, int dpadindex, int buttonindex) { Q_UNUSED(dpadindex); buttonDownEvent(setindex, buttonindex); } void InputDevice::dpadButtonUpEvent(int setindex, int dpadindex, int buttonindex) { Q_UNUSED(dpadindex); buttonUpEvent(setindex, buttonindex); } void InputDevice::stickButtonDownEvent(int setindex, int stickindex, int buttonindex) { Q_UNUSED(stickindex); buttonDownEvent(setindex, buttonindex); } void InputDevice::stickButtonUpEvent(int setindex, int stickindex, int buttonindex) { Q_UNUSED(stickindex); buttonUpEvent(setindex, buttonindex); } void InputDevice::sensorButtonDownEvent(int setindex, JoySensorType type, JoySensorDirection direction) { Q_UNUSED(type); buttonDownEvent(setindex, direction); } void InputDevice::sensorButtonUpEvent(int setindex, JoySensorType type, JoySensorDirection direction) { Q_UNUSED(type); buttonUpEvent(setindex, direction); } void InputDevice::setButtonName(int index, QString tempName) { for (auto &tempSet : getJoystick_sets()) { disconnect(tempSet, &SetJoystick::setButtonNameChange, this, &InputDevice::updateSetButtonNames); JoyButton *button = tempSet->getJoyButton(index); if (button != nullptr) button->setButtonName(tempName); connect(tempSet, &SetJoystick::setButtonNameChange, this, &InputDevice::updateSetButtonNames); } } void InputDevice::setAxisButtonName(int axisIndex, int buttonIndex, QString tempName) { for (auto &tempSet : getJoystick_sets()) { disconnect(tempSet, &SetJoystick::setAxisButtonNameChange, this, &InputDevice::updateSetAxisButtonNames); JoyAxis *axis = tempSet->getJoyAxis(axisIndex); if (axis != nullptr) { JoyAxisButton *button = nullptr; if (buttonIndex == 0) button = axis->getNAxisButton(); else if (buttonIndex == 1) button = axis->getPAxisButton(); if (button != nullptr) button->setButtonName(tempName); } connect(tempSet, &SetJoystick::setAxisButtonNameChange, this, &InputDevice::updateSetAxisButtonNames); } } void InputDevice::setStickButtonName(int stickIndex, int buttonIndex, QString tempName) { for (auto &tempSet : getJoystick_sets()) { disconnect(tempSet, &SetJoystick::setStickButtonNameChange, this, &InputDevice::updateSetStickButtonNames); JoyControlStick *stick = tempSet->getJoyStick(stickIndex); if (stick != nullptr) { JoyControlStickButton *button = stick->getDirectionButton(JoyControlStick::JoyStickDirections(buttonIndex)); if (button != nullptr) button->setButtonName(tempName); } connect(tempSet, &SetJoystick::setStickButtonNameChange, this, &InputDevice::updateSetStickButtonNames); } } /** * @brief Sets the name of a mapped sensor button in all sets * Used during XML loading. * @param type The sensor type which has the to be renamed button * @param direction The direction of the to be renamed button * @param tempName The new name */ void InputDevice::setSensorButtonName(JoySensorType type, JoySensorDirection direction, QString tempName) { auto sets = getJoystick_sets(); for (auto &tempSet : sets) { disconnect(tempSet, &SetJoystick::setStickButtonNameChange, this, &InputDevice::updateSetStickButtonNames); JoySensor *sensor = tempSet->getSensor(type); if (sensor != nullptr) { JoySensorButton *button = sensor->getDirectionButton(direction); if (button != nullptr) button->setButtonName(tempName); } connect(tempSet, &SetJoystick::setSensorButtonNameChange, this, &InputDevice::updateSetSensorButtonNames); } } void InputDevice::setDPadButtonName(int dpadIndex, int buttonIndex, QString tempName) { for (auto &tempSet : getJoystick_sets()) { disconnect(tempSet, &SetJoystick::setDPadButtonNameChange, this, &InputDevice::updateSetDPadButtonNames); JoyDPad *dpad = tempSet->getJoyDPad(dpadIndex); if (dpad != nullptr) { JoyDPadButton *button = dpad->getJoyButton(buttonIndex); if (button != nullptr) button->setButtonName(tempName); } connect(tempSet, &SetJoystick::setDPadButtonNameChange, this, &InputDevice::updateSetDPadButtonNames); } } void InputDevice::setVDPadButtonName(int vdpadIndex, int buttonIndex, QString tempName) { for (auto &tempSet : getJoystick_sets()) { disconnect(tempSet, &SetJoystick::setVDPadButtonNameChange, this, &InputDevice::updateSetVDPadButtonNames); VDPad *vdpad = tempSet->getVDPad(vdpadIndex); if (vdpad != nullptr) { JoyDPadButton *button = vdpad->getJoyButton(buttonIndex); if (button != nullptr) button->setButtonName(tempName); } connect(tempSet, &SetJoystick::setVDPadButtonNameChange, this, &InputDevice::updateSetVDPadButtonNames); } } void InputDevice::setAxisName(int axisIndex, QString tempName) { for (auto &tempSet : getJoystick_sets()) { disconnect(tempSet, &SetJoystick::setAxisNameChange, this, &InputDevice::updateSetAxisNames); JoyAxis *axis = tempSet->getJoyAxis(axisIndex); if (axis != nullptr) axis->setAxisName(tempName); connect(tempSet, &SetJoystick::setAxisNameChange, this, &InputDevice::updateSetAxisNames); } } void InputDevice::setStickName(int stickIndex, QString tempName) { for (auto &tempSet : getJoystick_sets()) { disconnect(tempSet, &SetJoystick::setStickNameChange, this, &InputDevice::updateSetStickNames); JoyControlStick *stick = tempSet->getJoyStick(stickIndex); if (stick != nullptr) stick->setStickName(tempName); connect(tempSet, &SetJoystick::setStickNameChange, this, &InputDevice::updateSetStickNames); } } /** * @brief Sets the name of a sensor in all sets * Used during XML loading. * @param type The sensor type to be renamed * @param tempName The new name */ void InputDevice::setSensorName(JoySensorType type, QString tempName) { auto sets = getJoystick_sets(); for (auto &tempSet : sets) { disconnect(tempSet, &SetJoystick::setSensorNameChange, this, &InputDevice::updateSetSensorNames); JoySensor *sensor = tempSet->getSensor(type); if (sensor != nullptr) sensor->setSensorName(tempName); connect(tempSet, &SetJoystick::setSensorNameChange, this, &InputDevice::updateSetSensorNames); } } void InputDevice::setDPadName(int dpadIndex, QString tempName) { for (auto &tempSet : getJoystick_sets()) { disconnect(tempSet, &SetJoystick::setDPadNameChange, this, &InputDevice::updateSetDPadNames); JoyDPad *dpad = tempSet->getJoyDPad(dpadIndex); if (dpad != nullptr) dpad->setDPadName(tempName); connect(tempSet, &SetJoystick::setDPadNameChange, this, &InputDevice::updateSetDPadNames); } } void InputDevice::setVDPadName(int vdpadIndex, QString tempName) { for (auto &tempSet : getJoystick_sets()) { disconnect(tempSet, &SetJoystick::setVDPadNameChange, this, &InputDevice::updateSetVDPadNames); VDPad *vdpad = tempSet->getVDPad(vdpadIndex); if (vdpad != nullptr) vdpad->setDPadName(tempName); connect(tempSet, &SetJoystick::setVDPadNameChange, this, &InputDevice::updateSetVDPadNames); } } void InputDevice::updateSetButtonNames(int index) { JoyButton *button = getActiveSetJoystick()->getJoyButton(index); if (button != nullptr) setButtonName(index, button->getButtonName()); } void InputDevice::updateSetAxisButtonNames(int axisIndex, int buttonIndex) { JoyAxis *axis = getActiveSetJoystick()->getJoyAxis(axisIndex); if (axis != nullptr) { JoyAxisButton *button = nullptr; if (buttonIndex == 0) button = axis->getNAxisButton(); else if (buttonIndex == 1) button = axis->getPAxisButton(); if (button != nullptr) setAxisButtonName(axisIndex, buttonIndex, button->getButtonName()); } } void InputDevice::updateSetStickButtonNames(int stickIndex, int buttonIndex) { JoyControlStick *stick = getActiveSetJoystick()->getJoyStick(stickIndex); if (stick != nullptr) { JoyControlStickButton *button = stick->getDirectionButton(JoyControlStick::JoyStickDirections(buttonIndex)); if (button != nullptr) setStickButtonName(stickIndex, buttonIndex, button->getButtonName()); } } /** * @brief Rename mapped sensor button in all sets to the name in the active set * @param type The sensor type which has the to be renamed button * @param direction The direction of the to be renamed button */ void InputDevice::updateSetSensorButtonNames(JoySensorType type, JoySensorDirection direction) { JoySensor *sensor = getActiveSetJoystick()->getSensor(type); if (sensor != nullptr) { JoySensorButton *button = sensor->getDirectionButton(direction); if (button != nullptr) setSensorButtonName(type, direction, button->getButtonName()); } } void InputDevice::updateSetDPadButtonNames(int dpadIndex, int buttonIndex) { JoyDPad *dpad = getActiveSetJoystick()->getJoyDPad(dpadIndex); if (dpad != nullptr) { JoyDPadButton *button = dpad->getJoyButton(buttonIndex); if (button != nullptr) setDPadButtonName(dpadIndex, buttonIndex, button->getButtonName()); } } void InputDevice::updateSetVDPadButtonNames(int vdpadIndex, int buttonIndex) { VDPad *vdpad = getActiveSetJoystick()->getVDPad(vdpadIndex); if (vdpad != nullptr) { JoyDPadButton *button = vdpad->getJoyButton(buttonIndex); if (button != nullptr) setVDPadButtonName(vdpadIndex, buttonIndex, button->getButtonName()); } } void InputDevice::updateSetAxisNames(int axisIndex) { JoyAxis *axis = getActiveSetJoystick()->getJoyAxis(axisIndex); if (axis != nullptr) setAxisName(axisIndex, axis->getAxisName()); } void InputDevice::updateSetStickNames(int stickIndex) { JoyControlStick *stick = getActiveSetJoystick()->getJoyStick(stickIndex); if (stick != nullptr) setStickName(stickIndex, stick->getStickName()); } /** * @brief Rename sensor in all sets to the name in the current set * @param type The sensor to rename */ void InputDevice::updateSetSensorNames(JoySensorType type) { JoySensor *sensor = getActiveSetJoystick()->getSensor(type); if (sensor != nullptr) setSensorName(type, sensor->getSensorName()); } void InputDevice::updateSetDPadNames(int dpadIndex) { JoyDPad *dpad = getActiveSetJoystick()->getJoyDPad(dpadIndex); if (dpad != nullptr) setDPadName(dpadIndex, dpad->getDpadName()); } void InputDevice::updateSetVDPadNames(int vdpadIndex) { VDPad *vdpad = getActiveSetJoystick()->getVDPad(vdpadIndex); if (vdpad != nullptr) setVDPadName(vdpadIndex, vdpad->getDpadName()); } void InputDevice::resetButtonDownCount() { buttonDownCount = 0; emit released(joyNumber); } /** * @brief Establishes necessary connections for set change slots */ void InputDevice::enableSetConnections(SetJoystick *setstick) { connect(setstick, &SetJoystick::setChangeActivated, this, &InputDevice::resetButtonDownCount); connect(setstick, &SetJoystick::setChangeActivated, this, &InputDevice::setActiveSetNumber); connect(setstick, &SetJoystick::setChangeActivated, this, &InputDevice::propogateSetChange); connect(setstick, &SetJoystick::setAssignmentButtonChanged, this, &InputDevice::changeSetButtonAssociation); connect(setstick, &SetJoystick::setAssignmentAxisChanged, this, &InputDevice::changeSetAxisButtonAssociation); connect(setstick, &SetJoystick::setAssignmentDPadChanged, this, &InputDevice::changeSetDPadButtonAssociation); connect(setstick, &SetJoystick::setAssignmentVDPadChanged, this, &InputDevice::changeSetVDPadButtonAssociation); connect(setstick, &SetJoystick::setAssignmentStickChanged, this, &InputDevice::changeSetStickButtonAssociation); connect(setstick, &SetJoystick::setAssignmentSensorChanged, this, &InputDevice::changeSetSensorButtonAssociation); connect(setstick, &SetJoystick::setAssignmentAxisThrottleChanged, this, &InputDevice::propogateSetAxisThrottleChange); connect(setstick, &SetJoystick::setButtonClick, this, &InputDevice::buttonDownEvent); connect(setstick, &SetJoystick::setButtonRelease, this, &InputDevice::buttonUpEvent); connect(setstick, &SetJoystick::setAxisButtonClick, this, &InputDevice::axisButtonDownEvent); connect(setstick, &SetJoystick::setAxisButtonRelease, this, &InputDevice::axisButtonUpEvent); connect(setstick, &SetJoystick::setAxisActivated, this, &InputDevice::axisActivatedEvent); connect(setstick, &SetJoystick::setAxisReleased, this, &InputDevice::axisReleasedEvent); connect(setstick, &SetJoystick::setDPadButtonClick, this, &InputDevice::dpadButtonDownEvent); connect(setstick, &SetJoystick::setDPadButtonRelease, this, &InputDevice::dpadButtonUpEvent); connect(setstick, &SetJoystick::setStickButtonClick, this, &InputDevice::stickButtonDownEvent); connect(setstick, &SetJoystick::setStickButtonRelease, this, &InputDevice::stickButtonUpEvent); connect(setstick, &SetJoystick::setSensorButtonClick, this, &InputDevice::sensorButtonDownEvent); connect(setstick, &SetJoystick::setSensorButtonRelease, this, &InputDevice::sensorButtonUpEvent); connect(setstick, &SetJoystick::setButtonNameChange, this, &InputDevice::updateSetButtonNames); connect(setstick, &SetJoystick::setAxisButtonNameChange, this, &InputDevice::updateSetAxisButtonNames); connect(setstick, &SetJoystick::setStickButtonNameChange, this, &InputDevice::updateSetStickButtonNames); connect(setstick, &SetJoystick::setSensorButtonNameChange, this, &InputDevice::updateSetSensorButtonNames); connect(setstick, &SetJoystick::setDPadButtonNameChange, this, &InputDevice::updateSetDPadButtonNames); connect(setstick, &SetJoystick::setVDPadButtonNameChange, this, &InputDevice::updateSetVDPadButtonNames); connect(setstick, &SetJoystick::setAxisNameChange, this, &InputDevice::updateSetAxisNames); connect(setstick, &SetJoystick::setStickNameChange, this, &InputDevice::updateSetStickNames); connect(setstick, &SetJoystick::setSensorNameChange, this, &InputDevice::updateSetSensorNames); connect(setstick, &SetJoystick::setDPadNameChange, this, &InputDevice::updateSetDPadNames); connect(setstick, &SetJoystick::setVDPadNameChange, this, &InputDevice::updateSetVDPadNames); } void InputDevice::axisActivatedEvent(int setindex, int axisindex, int value) { Q_UNUSED(setindex); emit rawAxisActivated(axisindex, value); } void InputDevice::axisReleasedEvent(int setindex, int axisindex, int value) { Q_UNUSED(setindex); emit rawAxisReleased(axisindex, value); } void InputDevice::setIndex(int index) { if (index >= 0) joyNumber = index; else joyNumber = 0; } void InputDevice::setDeviceKeyPressTime(int newPressTime) { keyPressTime = newPressTime; emit propertyUpdated(); } int InputDevice::getDeviceKeyPressTime() { return keyPressTime; } void InputDevice::profileEdited() { if (!deviceEdited) { deviceEdited = true; emit profileUpdated(); } } bool InputDevice::isDeviceEdited() { return deviceEdited; } void InputDevice::revertProfileEdited() { deviceEdited = false; } QString InputDevice::getStringIdentifier() { QString identifier = QString(); // QString tempGUID = getGUIDString(); QString tempUniqueID = getUniqueIDString(); QString tempName = getSDLName(); if (!tempUniqueID.isEmpty()) identifier = tempUniqueID; // else if (!tempGUID.isEmpty()) identifier = tempGUID; else if (!tempName.isEmpty()) identifier = tempName; return identifier; } void InputDevice::establishPropertyUpdatedConnection() { connect(this, &InputDevice::propertyUpdated, this, &InputDevice::profileEdited); } void InputDevice::disconnectPropertyUpdatedConnection() { disconnect(this, &InputDevice::propertyUpdated, this, &InputDevice::profileEdited); } void InputDevice::setKeyRepeatStatus(bool enabled) { keyRepeatEnabled = enabled; } void InputDevice::setKeyRepeatDelay(int delay) { if ((delay >= 250) && (delay <= 1000)) { keyRepeatDelay = delay; } } void InputDevice::setKeyRepeatRate(int rate) { if ((rate >= 20) && (rate <= 200)) { keyRepeatRate = rate; } } bool InputDevice::isKeyRepeatEnabled() { return keyRepeatEnabled; } int InputDevice::getKeyRepeatDelay() { int tempKeyRepeatDelay = GlobalVariables::InputDevice::DEFAULTKEYREPEATDELAY; if (keyRepeatDelay != 0) { tempKeyRepeatDelay = keyRepeatDelay; } return tempKeyRepeatDelay; } int InputDevice::getKeyRepeatRate() { int tempKeyRepeatRate = GlobalVariables::InputDevice::DEFAULTKEYREPEATRATE; if (keyRepeatRate != 0) { tempKeyRepeatRate = keyRepeatRate; } return tempKeyRepeatRate; } void InputDevice::setProfileName(QString value) { if (profileName != value) { if (value.size() > 50) { value.truncate(47); value.append("..."); } profileName = value; emit propertyUpdated(); emit profileNameEdited(value); } } QString InputDevice::getProfileName() { return profileName; } int InputDevice::getButtonDownCount() { return buttonDownCount; } QString InputDevice::getDescription() { QString full_desc = QString("Index: %1").arg(getRealJoyNumber()) + "\n " + QString("UniqueID: %1").arg(getUniqueIDString()) + "\n " + QString("GUID: %1").arg(getGUIDString()) + "\n " + QString("VendorID: %1").arg(getVendorString()) + "\n " + QString("ProductID: %1").arg(getProductIDString()) + "\n " + QString("Serial: %1").arg(getSerialString()) + "\n " + QString("Product Version: %1").arg(getProductVersion()) + "\n " + QString("Name: %1").arg(getSDLName()) + "\n"; QString gameControllerStatus = isGameController() ? QString("Yes") : QString("No"); full_desc = full_desc + " " + QString("Game Controller: %1").arg(gameControllerStatus) + "\n " + QString("# of Axes: %1").arg(getNumberRawAxes()) + "\n " + QString("# of Buttons: %1").arg(getNumberRawButtons()) + "\n " + QString("# of Hats: %1").arg(getNumberHats()) + "\n " + QString("Accelerometer: %1").arg(hasSensor(ACCELEROMETER)) + "\n " + QString("Gyroscope: %1").arg(hasSensor(GYROSCOPE)) + "\n"; return full_desc; } QString InputDevice::getSDLPlatform() { QString temp = SDL_GetPlatform(); return temp; } /** * @brief Check if device is using the SDL Game Controller API * @return Status showing if device is using the Game Controller API */ bool InputDevice::isGameController() { return false; } bool InputDevice::hasCalibrationThrottle(int axisNum) { bool result = false; if (getCali().contains(axisNum)) result = true; return result; } JoyAxis::ThrottleTypes InputDevice::getCalibrationThrottle(int axisNum) { return getCali().value(axisNum); } void InputDevice::setCalibrationThrottle(int axisNum, JoyAxis::ThrottleTypes throttle) { if (!getCali().contains(axisNum)) { for (int i = 0; i < GlobalVariables::InputDevice::NUMBER_JOYSETS; i++) { getJoystick_sets().value(i)->setAxisThrottle(axisNum, throttle); } getCali().insert(axisNum, throttle); } } void InputDevice::setCalibrationStatus(int axisNum, JoyAxis::ThrottleTypes throttle) { if (!getCali().contains(axisNum)) getCali().insert(axisNum, throttle); } void InputDevice::removeCalibrationStatus(int axisNum) { if (getCali().contains(axisNum)) getCali().remove(axisNum); } void InputDevice::sendLoadProfileRequest(QString location) { if (!location.isEmpty()) emit requestProfileLoad(location); } AntiMicroSettings *InputDevice::getSettings() { return m_settings; } bool InputDevice::isKnownController() { bool result = false; if (isGameController()) { result = true; } else { m_settings->beginGroup("Mappings"); // if (m_settings->contains(getGUIDString())) result = true; // else if (m_settings->contains(QString("%1%2").arg(getGUIDString()).arg("Disabled"))) result = true; convertToUniqueMappSett(m_settings, getGUIDString(), getUniqueIDString()); convertToUniqueMappSett(m_settings, (QString("%1%2").arg(getGUIDString()).arg("Disabled")), (QString("%1%2").arg(getUniqueIDString()).arg("Disabled"))); if (m_settings->contains(getUniqueIDString())) result = true; else if (m_settings->contains(QString("%1%2").arg(getUniqueIDString()).arg("Disabled"))) result = true; m_settings->endGroup(); } return result; } void InputDevice::activatePossiblePendingEvents() { activatePossibleControlStickEvents(); activatePossibleAxisEvents(); activatePossibleDPadEvents(); activatePossibleVDPadEvents(); activatePossibleButtonEvents(); } void InputDevice::activatePossibleControlStickEvents() { SetJoystick *currentSet = getActiveSetJoystick(); for (int i = 0; i < currentSet->getNumberSticks(); i++) { JoyControlStick *tempStick = currentSet->getJoyStick(i); if ((tempStick != nullptr) && tempStick->hasPendingEvent()) { tempStick->activatePendingEvent(); } } } void InputDevice::activatePossibleAxisEvents() { SetJoystick *currentSet = getActiveSetJoystick(); for (int i = 0; i < currentSet->getNumberAxes(); i++) { JoyAxis *tempAxis = currentSet->getJoyAxis(i); if ((tempAxis != nullptr) && tempAxis->hasPendingEvent()) { tempAxis->activatePendingEvent(); } } } void InputDevice::activatePossibleSensorEvents() { SetJoystick *currentSet = getActiveSetJoystick(); JoySensor *sensor = nullptr; for (size_t i = 0; i < SENSOR_COUNT; ++i) { JoySensorType type = static_cast(i); sensor = currentSet->getSensor(type); if ((sensor != nullptr) && sensor->hasPendingEvent()) sensor->activatePendingEvent(); } } void InputDevice::activatePossibleDPadEvents() { SetJoystick *currentSet = getActiveSetJoystick(); for (int i = 0; i < currentSet->getNumberHats(); i++) { JoyDPad *tempDPad = currentSet->getJoyDPad(i); if ((tempDPad != nullptr) && tempDPad->hasPendingEvent()) tempDPad->activatePendingEvent(); } } void InputDevice::activatePossibleVDPadEvents() { SetJoystick *currentSet = getActiveSetJoystick(); for (int i = 0; i < currentSet->getNumberVDPads(); i++) { VDPad *tempVDPad = currentSet->getVDPad(i); if ((tempVDPad != nullptr) && tempVDPad->hasPendingEvent()) tempVDPad->activatePendingEvent(); } } void InputDevice::activatePossibleButtonEvents() { SetJoystick *currentSet = getActiveSetJoystick(); for (int i = 0; i < currentSet->getNumberButtons(); i++) { JoyButton *tempButton = currentSet->getJoyButton(i); if ((tempButton != nullptr) && tempButton->hasPendingEvent()) tempButton->activatePendingEvent(); } } bool InputDevice::elementsHaveNames() { bool result = false; SetJoystick *tempSet = getActiveSetJoystick(); for (int i = 0; i < getNumberButtons() && !result; i++) { JoyButton *button = tempSet->getJoyButton(i); if ((button != nullptr) && !button->getButtonName().isEmpty()) result = true; } for (int i = 0; (i < getNumberAxes()) && !result; i++) { JoyAxis *axis = tempSet->getJoyAxis(i); if (axis != nullptr) { if (!axis->getAxisName().isEmpty()) result = true; JoyAxisButton *naxisbutton = axis->getNAxisButton(); if (!naxisbutton->getButtonName().isEmpty()) result = true; JoyAxisButton *paxisbutton = axis->getPAxisButton(); if (!paxisbutton->getButtonName().isEmpty()) result = true; } } for (int i = 0; (i < getNumberSticks()) && !result; i++) { JoyControlStick *stick = tempSet->getJoyStick(i); if (stick != nullptr) { if (!stick->getStickName().isEmpty()) result = true; QHash *buttons = stick->getButtons(); QHashIterator iter(*buttons); while (iter.hasNext() && !result) { JoyControlStickButton *button = iter.next().value(); if (button && !button->getButtonName().isEmpty()) result = true; } } } for (int i = 0; (i < getNumberHats()) && !result; i++) { JoyDPad *dpad = tempSet->getJoyDPad(i); if (dpad != nullptr) { if (!dpad->getDpadName().isEmpty()) result = true; QHash *temp = dpad->getButtons(); QHashIterator iter(*temp); while (iter.hasNext() && !result) { JoyDPadButton *button = iter.next().value(); if (button && !button->getButtonName().isEmpty()) result = true; } } } for (int i = 0; (i < getNumberVDPads()) && !result; i++) { VDPad *vdpad = getActiveSetJoystick()->getVDPad(i); if (vdpad != nullptr) { if (!vdpad->getDpadName().isEmpty()) result = true; QHash *temp = vdpad->getButtons(); QHashIterator iter(*temp); while (iter.hasNext() && !result) { JoyDPadButton *button = iter.next().value(); if ((button != nullptr) && !button->getButtonName().isEmpty()) result = true; } } } return result; } /** * @brief Check if the GUID passed is considered empty. * @param GUID string * @return if GUID is considered empty. */ // bool InputDevice::isEmptyGUID(QString tempGUID) //{ // bool result = false; // if (tempGUID.contains(GlobalVariables::InputDevice::emptyGUID)) result = true; // return result; //} bool InputDevice::isEmptyUniqueID(QString tempUniqueID) { bool result = false; if (tempUniqueID.contains(GlobalVariables::InputDevice::emptyUniqueID)) result = true; return result; } /** * @brief Check if GUID passed matches the expected GUID for a device. * Needed for xinput GUID abstraction. * @param GUID string * @return if GUID is considered a match. */ // bool InputDevice::isRelevantGUID(QString tempGUID) //{ // bool result = false; // if (tempGUID == getGUIDString()) result = true; // return result; //} bool InputDevice::isRelevantUniqueID(QString tempUniqueID) { bool result = false; if (tempUniqueID == getUniqueIDString()) result = true; return result; } QString InputDevice::getRawGUIDString() const { return getGUIDString(); } QString InputDevice::getRawVendorString() const { return getVendorString(); } QString InputDevice::getRawProductIDString() const { return getProductIDString(); } QString InputDevice::getRawProductVersion() const { return getProductVersion(); } QString InputDevice::getRawUniqueIDString() const { return getUniqueIDString(); } void InputDevice::haltServices() { emit requestWait(); } void InputDevice::finalRemoval() { this->closeSDLDevice(); this->deleteLater(); } void InputDevice::setRawAxisDeadZone(int deadZone) { if ((deadZone > 0) && (deadZone <= GlobalVariables::JoyAxis::AXISMAX)) { this->rawAxisDeadZone = deadZone; } else { this->rawAxisDeadZone = GlobalVariables::InputDevice::RAISEDDEADZONE; } } int InputDevice::getRawAxisDeadZone() { return rawAxisDeadZone; } void InputDevice::rawAxisEvent(int index, int value) { emit rawAxisMoved(index, value); } void InputDevice::convertToUniqueMappSett(QSettings *sett, QString gUIDmappGroupSett, QString uniqueIDGroupSett) { if (sett->contains(gUIDmappGroupSett)) { if (sett->contains(gUIDmappGroupSett) && (sett->value(gUIDmappGroupSett).toString().split(",").first() == getGUIDString())) { QStringList gg = sett->value(gUIDmappGroupSett).toString().split(","); gg.removeFirst(); gg.prepend(uniqueIDGroupSett); sett->setValue(uniqueIDGroupSett, sett->value(gg.join(","))); sett->remove(gUIDmappGroupSett); } else { sett->setValue(uniqueIDGroupSett, sett->value(gUIDmappGroupSett)); sett->remove(gUIDmappGroupSett); } } } QMap &InputDevice::getJoystick_sets() { return joystick_sets; } QHash &InputDevice::getCali() { return cali; } SDL_JoystickID *InputDevice::getJoystickID() { return &joystickID; } QList &InputDevice::getButtonstatesLocal() { return buttonstates; } QList &InputDevice::getAxesstatesLocal() { return axesstates; } QList &InputDevice::getDpadstatesLocal() { return dpadstates; } SDL_Joystick *InputDevice::getJoyHandle() const { return m_joyhandle; } /** * @brief Returns the current controller model. * For non gamecontroller devices it always returns UNKNOWN. */ SDL_GameControllerType InputDevice::getControllerType() const { return SDL_CONTROLLER_TYPE_UNKNOWN; } /** * @brief Returns a pointer to the internal calibration storage backend. */ InputDeviceCalibration *InputDevice::getCalibrationBackend() { return &m_calibrations; } /** * @brief Updates stored calibration for this controller and applies * calibration to the specified stick in all sets * See JoyControlStick::setCalibration * @param[in] index Stick index * @param[in] offsetX Offset value for X axis * @param[in] gainX Gain value for X axis * @param[in] offsetY Offset value for Y axis * @param[in] gainY Gain value for Y axis */ void InputDevice::updateStickCalibration(int index, double offsetX, double gainX, double offsetY, double gainY) { m_calibrations.setStickCalibration(index, offsetX, gainX, offsetY, gainY); applyStickCalibration(index, offsetX, gainX, offsetY, gainY); } /** * @brief Applies calibration to the specified stick in all sets * See JoyControlStick::setCalibration * @param[in] index Stick index * @param[in] offsetX Offset value for X axis * @param[in] gainX Gain value for X axis * @param[in] offsetY Offset value for Y axis * @param[in] gainY Gain value for Y axis */ void InputDevice::applyStickCalibration(int index, double offsetX, double gainX, double offsetY, double gainY) { for (auto &set : joystick_sets) { JoyControlStick *stick = set->getSticks().value(index); if (stick != nullptr) stick->setCalibration(offsetX, gainX, offsetY, gainY); } } /** * @brief Applies calibration to the specified accelerometer in all sets * See JoySensor::setCalibration * @param[in] offsetX Offset angle around the X axis * @param[in] offsetY Offset angle around the Y axis * @param[in] offsetZ Offset angle around the Z axis */ void InputDevice::updateAccelerometerCalibration(double offsetX, double offsetY, double offsetZ) { m_calibrations.setAccelerometerCalibration(offsetX, offsetY, offsetZ); applyAccelerometerCalibration(offsetX, offsetY, offsetZ); } /** * @brief Applies calibration to the specified accelerometer in all sets * See JoySensor::setCalibration * @param[in] offsetX Offset angle around the X axis * @param[in] offsetY Offset angle around the Y axis * @param[in] offsetZ Offset angle around the Z axis */ void InputDevice::applyAccelerometerCalibration(double offsetX, double offsetY, double offsetZ) { for (auto &set : joystick_sets) { JoySensor *accelerometer = set->getSensor(ACCELEROMETER); if (accelerometer != nullptr) accelerometer->setCalibration(offsetX, offsetY, offsetZ); } } /** * @brief Updates stored calibration for this controller and applies * calibration to the specified gyroscope in all sets * See JoySensor::setCalibration * @param[in] offsetX Offset value for X axis * @param[in] offsetY Offset value for Y axis * @param[in] offsetZ Offset value for Z axis */ void InputDevice::updateGyroscopeCalibration(double offsetX, double offsetY, double offsetZ) { m_calibrations.setGyroscopeCalibration(offsetX, offsetY, offsetZ); applyGyroscopeCalibration(offsetX, offsetY, offsetZ); } /** * @brief Applies calibration to the specified gyroscope in all sets * See JoySensor::setCalibration * @param[in] offsetX Offset value for X axis * @param[in] offsetY Offset value for Y axis * @param[in] offsetZ Offset value for Z axis */ void InputDevice::applyGyroscopeCalibration(double offsetX, double offsetY, double offsetZ) { for (auto &set : joystick_sets) { JoySensor *gyroscope = set->getSensor(GYROSCOPE); if (gyroscope != nullptr) gyroscope->setCalibration(offsetX, offsetY, offsetZ); } } AntiMicroX-antimicrox-b300273/src/inputdevice.h000066400000000000000000000317571471077622000214460ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef INPUTDEVICE_H #define INPUTDEVICE_H #include "inputdevicecalibration.h" #include "joysensordirection.h" #include "joysensortype.h" #include "setjoystick.h" #include class AntiMicroSettings; class SetJoystick; class QXmlStreamReader; class QXmlStreamWriter; class QSettings; #if not SDL_VERSION_ATLEAST(2, 0, 12) enum SDL_GameControllerType { SDL_CONTROLLER_TYPE_UNKNOWN = 0 }; #endif /** * @brief Abstract class representing a hardware input device, e.g a joystick or controller. * * @details Two concrete implementations are Joystick and class GameController * difference between two of them are described in listed sources * @see https://discourse.libsdl.org/t/difference-between-joysticks-and-game-controllers/24028/2 * @see https://stackoverflow.com/a/50026410/11747535 */ class InputDevice : public QObject { Q_OBJECT public: explicit InputDevice(SDL_Joystick *joystick, int deviceIndex, AntiMicroSettings *settings, QObject *parent); virtual ~InputDevice(); virtual int getNumberButtons(); virtual int getNumberAxes(); virtual int getNumberHats(); virtual int getNumberSticks(); virtual bool hasSensor(JoySensorType type); virtual int getNumberVDPads(); int getJoyNumber(); int getRealJoyNumber(); int getActiveSetNumber(); SetJoystick *getActiveSetJoystick(); SetJoystick *getSetJoystick(int index); void removeControlStick(int index); bool isActive(); int getButtonDownCount(); virtual QString getXmlName() const = 0; virtual QString getName() = 0; virtual QString getSDLName() = 0; virtual QString getDescription(); // GUID only available on SDL 2. virtual QString getGUIDString() const = 0; virtual QString getUniqueIDString() const = 0; virtual QString getVendorString() const = 0; virtual QString getSerialString() const = 0; virtual QString getProductIDString() const = 0; virtual QString getProductVersion() const = 0; virtual QString getRawGUIDString() const; virtual QString getRawVendorString() const; virtual QString getRawProductIDString() const; virtual QString getRawProductVersion() const; virtual QString getRawUniqueIDString() const; virtual void setCounterUniques(int counter) = 0; virtual QString getStringIdentifier(); virtual void closeSDLDevice() = 0; virtual SDL_JoystickID getSDLJoystickID() = 0; QString getSDLPlatform(); virtual bool isGameController(); virtual bool isKnownController(); void setButtonName(int index, QString tempName); // InputDeviceXml class void setAxisButtonName(int axisIndex, int buttonIndex, QString tempName); // InputDeviceXml class void setStickButtonName(int stickIndex, int buttonIndex, QString tempName); // InputDeviceXml class void setSensorButtonName(JoySensorType type, JoySensorDirection direction, QString tempName); void setDPadButtonName(int dpadIndex, int buttonIndex, QString tempName); // InputDeviceXml class void setVDPadButtonName(int vdpadIndex, int buttonIndex, QString tempName); // InputDeviceXml class void setAxisName(int axisIndex, QString tempName); // InputDeviceAxis class void setStickName(int stickIndex, QString tempName); // InputDeviceStick class void setSensorName(JoySensorType type, QString tempName); void setDPadName(int dpadIndex, QString tempName); // InputDeviceHat class void setVDPadName(int vdpadIndex, QString tempName); // InputDeviceVDPad class virtual int getNumberRawButtons() = 0; virtual int getNumberRawAxes() = 0; virtual int getNumberRawHats() = 0; virtual double getRawSensorRate(JoySensorType type) = 0; virtual bool hasRawSensor(JoySensorType type) = 0; int getDeviceKeyPressTime(); // unsigned void setIndex(int index); bool isDeviceEdited(); void revertProfileEdited(); void setKeyRepeatStatus(bool enabled); void setKeyRepeatDelay(int delay); void setKeyRepeatRate(int rate); bool isKeyRepeatEnabled(); int getKeyRepeatDelay(); int getKeyRepeatRate(); QString getProfileName(); bool hasCalibrationThrottle(int axisNum); JoyAxis::ThrottleTypes getCalibrationThrottle(int axisNum); void setCalibrationThrottle(int axisNum, JoyAxis::ThrottleTypes throttle); void setCalibrationStatus(int axisNum, JoyAxis::ThrottleTypes throttle); void removeCalibrationStatus(int axisNum); void sendLoadProfileRequest(QString location); AntiMicroSettings *getSettings(); void activatePossiblePendingEvents(); void activatePossibleControlStickEvents(); // InputDeviceStick class void activatePossibleAxisEvents(); // InputDeviceAxis class void activatePossibleSensorEvents(); void activatePossibleDPadEvents(); // InputDeviceHat class void activatePossibleVDPadEvents(); // InputDeviceVDPad class void activatePossibleButtonEvents(); // InputDeviceButton class void convertToUniqueMappSett(QSettings *sett, QString gUIDmappGroupSett, QString uniqueIDGroupSett); // bool isEmptyGUID(QString tempGUID); bool isEmptyUniqueID(QString tempUniqueID); // bool isRelevantGUID(QString tempGUID); bool isRelevantUniqueID(QString tempUniqueID); void setRawAxisDeadZone(int deadZone); // InputDeviceAxis class int getRawAxisDeadZone(); // InputDeviceAxis class void rawAxisEvent(int index, int value); // InputDeviceAxis class bool elementsHaveNames(); QMap &getJoystick_sets(); SDL_Joystick *getJoyHandle() const; virtual SDL_GameControllerType getControllerType() const; InputDeviceCalibration *getCalibrationBackend(); void updateStickCalibration(int index, double offsetX, double gainX, double offsetY, double gainY); void applyStickCalibration(int index, double offsetX, double gainX, double offsetY, double gainY); void updateAccelerometerCalibration(double offsetX, double offsetY, double offsetZ); void applyAccelerometerCalibration(double offsetX, double offsetY, double offsetZ); void updateGyroscopeCalibration(double offsetX, double offsetY, double offsetZ); void applyGyroscopeCalibration(double offsetX, double offsetY, double offsetZ); protected: void enableSetConnections(SetJoystick *setstick); QHash &getCali(); SDL_JoystickID *getJoystickID(); int rawAxisDeadZone; int keyPressTime; // unsigned QString profileName; InputDeviceCalibration m_calibrations; signals: void setChangeActivated(int index); void setAxisThrottleActivated(int index); // InputDeviceAxis class void clicked(int index); void released(int index); void rawButtonClick(int index); // InputDeviceButton class void rawButtonRelease(int index); // InputDeviceButton class void rawAxisButtonClick(int axis, int buttonindex); // InputDeviceAxisBtn class void rawAxisButtonRelease(int axis, int buttonindex); // InputDeviceAxisBtn class void rawDPadButtonClick(int dpad, int buttonindex); // InputDeviceHat class void rawDPadButtonRelease(int dpad, int buttonindex); // InputDeviceHat class void rawAxisActivated(int axis, int value); // InputDeviceAxis class void rawAxisReleased(int axis, int value); // InputDeviceAxis class void rawAxisMoved(int axis, int value); // InputDeviceAxis class void profileUpdated(); void propertyUpdated(); void profileNameEdited(QString text); void requestProfileLoad(QString location); void requestWait(); public slots: void reset(); void transferReset(); void reInitButtons(); void resetButtonDownCount(); void setActiveSetNumber(int index); void changeSetButtonAssociation(int button_index, int originset, int newset, int mode); // InputDeviceButton class void changeSetAxisButtonAssociation(int button_index, int axis_index, int originset, int newset, int mode); // InputDeviceAxisBtn class void changeSetStickButtonAssociation(int button_index, int stick_index, int originset, int newset, int mode); // InputDeviceStick class void changeSetSensorButtonAssociation(JoySensorDirection direction, JoySensorType type, int originset, int newset, int mode); void changeSetDPadButtonAssociation(int button_index, int dpad_index, int originset, int newset, int mode); // InputDeviceHat class void changeSetVDPadButtonAssociation(int button_index, int dpad_index, int originset, int newset, int mode); // InputDeviceVDPad class void setDeviceKeyPressTime(int newPressTime); // .., unsigned void profileEdited(); void setProfileName(QString value); void haltServices(); void finalRemoval(); virtual void buttonClickEvent(int buttonindex); // InputDeviceButton class virtual void buttonReleaseEvent(int buttonindex); // InputDeviceButton class virtual void dpadButtonClickEvent(int buttonindex); // InputDeviceHat class virtual void dpadButtonReleaseEvent(int buttonindex); // InputDeviceHat class void establishPropertyUpdatedConnection(); void disconnectPropertyUpdatedConnection(); protected slots: void propogateSetChange(int index); void propogateSetAxisThrottleChange(int index, int originset); void buttonDownEvent(int setindex, int buttonindex); // InputDeviceButton class void buttonUpEvent(int setindex, int buttonindex); // InputDeviceButton class virtual void axisActivatedEvent(int setindex, int axisindex, int value); // InputDeviceAxis class virtual void axisReleasedEvent(int setindex, int axisindex, int value); // InputDeviceAxis class virtual void axisButtonDownEvent(int setindex, int axisindex, int buttonindex); // InputDeviceAxisBtn class virtual void axisButtonUpEvent(int setindex, int axisindex, int buttonindex); // InputDeviceAxisBtn class virtual void dpadButtonDownEvent(int setindex, int dpadindex, int buttonindex); // InputDeviceHat class virtual void dpadButtonUpEvent(int setindex, int dpadindex, int buttonindex); // InputDeviceHat class virtual void stickButtonDownEvent(int setindex, int stickindex, int buttonindex); // InputDeviceStick class virtual void stickButtonUpEvent(int setindex, int stickindex, int buttonindex); // InputDeviceStick class virtual void sensorButtonDownEvent(int setindex, JoySensorType type, JoySensorDirection direction); virtual void sensorButtonUpEvent(int setindex, JoySensorType type, JoySensorDirection direction); void updateSetButtonNames(int index); // InputDeviceButton class void updateSetAxisButtonNames(int axisIndex, int buttonIndex); // InputDeviceAxis class void updateSetStickButtonNames(int stickIndex, int buttonIndex); // InputDeviceStick class void updateSetSensorButtonNames(JoySensorType type, JoySensorDirection direction); void updateSetDPadButtonNames(int dpadIndex, int buttonIndex); // InputDeviceHat class void updateSetVDPadButtonNames(int vdpadIndex, int buttonIndex); // InputDeviceVDPad class void updateSetAxisNames(int axisIndex); // InputDeviceAxis class void updateSetStickNames(int stickIndex); // InputDeviceStick class void updateSetSensorNames(JoySensorType type); void updateSetDPadNames(int dpadIndex); // InputDeviceHat class void updateSetVDPadNames(int vdpadIndex); // InputDeviceVDPad class private: QList &getButtonstatesLocal(); QList &getAxesstatesLocal(); QList &getDpadstatesLocal(); SDL_Joystick *m_joyhandle; QMap joystick_sets; QHash cali; AntiMicroSettings *m_settings; int active_set; int joyNumber; int buttonDownCount; SDL_JoystickID joystickID; bool deviceEdited; bool keyRepeatEnabled; int keyRepeatDelay; int keyRepeatRate; QList buttonstates; QList axesstates; QList dpadstates; }; Q_DECLARE_METATYPE(InputDevice *) Q_DECLARE_METATYPE(SDL_JoystickID) #endif // INPUTDEVICE_H AntiMicroX-antimicrox-b300273/src/inputdevicebitarraystatus.cpp000066400000000000000000000111471471077622000247720ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "inputdevicebitarraystatus.h" #include "inputdevice.h" #include "joybuttontypes/joybutton.h" #include "joydpad.h" #include "joystick.h" #include "setjoystick.h" #include InputDeviceBitArrayStatus::InputDeviceBitArrayStatus(InputDevice *device, bool readCurrent, QObject *parent) : QObject(parent) { for (int i = 0; i < device->getNumberRawAxes(); i++) { SetJoystick *currentSet = device->getActiveSetJoystick(); JoyAxis *axis = currentSet->getJoyAxis(i); if ((axis != nullptr) && readCurrent) { axesStatus.append(!axis->inDeadZone(axis->getCurrentRawValue()) ? true : false); } else { axesStatus.append(false); } } for (int i = 0; i < device->getNumberRawHats(); i++) { SetJoystick *currentSet = device->getActiveSetJoystick(); JoyDPad *dpad = currentSet->getJoyDPad(i); if ((dpad != nullptr) && readCurrent) { hatButtonStatus.append(dpad->getCurrentDirection() != JoyDPadButton::DpadCentered ? true : false); } else { hatButtonStatus.append(false); } } getButtonStatusLocal().resize(device->getNumberRawButtons()); getButtonStatusLocal().fill(0); for (int i = 0; i < device->getNumberRawButtons(); i++) { SetJoystick *currentSet = device->getActiveSetJoystick(); JoyButton *button = currentSet->getJoyButton(i); if ((button != nullptr) && readCurrent) { getButtonStatusLocal().setBit(i, button->getButtonState()); } } m_sensor_status.resize(SENSOR_COUNT); m_sensor_status.fill(0); } void InputDeviceBitArrayStatus::changeAxesStatus(int axisIndex, bool value) { if ((axisIndex >= 0) && (axisIndex <= axesStatus.size())) { axesStatus.replace(axisIndex, value); } } void InputDeviceBitArrayStatus::changeButtonStatus(int buttonIndex, bool value) { if ((buttonIndex >= 0) && (buttonIndex <= getButtonStatusLocal().size())) { getButtonStatusLocal().setBit(buttonIndex, value); } } void InputDeviceBitArrayStatus::changeHatStatus(int hatIndex, bool value) { if ((hatIndex >= 0) && (hatIndex <= hatButtonStatus.size())) { hatButtonStatus.replace(hatIndex, value); } } void InputDeviceBitArrayStatus::changeSensorStatus(int sensorIndex, bool value) { if ((sensorIndex >= 0) && (sensorIndex <= m_sensor_status.size())) { m_sensor_status.setBit(sensorIndex, value); } } QBitArray InputDeviceBitArrayStatus::generateFinalBitArray() { int totalArraySize = 0; totalArraySize = axesStatus.size() + hatButtonStatus.size() + getButtonStatusLocal().size() + m_sensor_status.size(); QBitArray aggregateBitArray(totalArraySize, false); int currentBit = 0; for (int i = 0; i < axesStatus.size(); i++) { aggregateBitArray.setBit(currentBit, axesStatus.at(i)); currentBit++; } for (int i = 0; i < hatButtonStatus.size(); i++) { aggregateBitArray.setBit(currentBit, hatButtonStatus.at(i)); currentBit++; } for (int i = 0; i < getButtonStatusLocal().size(); i++) { aggregateBitArray.setBit(currentBit, getButtonStatusLocal().at(i)); currentBit++; } for (int i = 0; i < SENSOR_COUNT; i++) { aggregateBitArray.setBit(currentBit, m_sensor_status.at(i)); currentBit++; } return aggregateBitArray; } void InputDeviceBitArrayStatus::clearStatusValues() { for (int i = 0; i < axesStatus.size(); i++) axesStatus.replace(i, false); for (int i = 0; i < hatButtonStatus.size(); i++) hatButtonStatus.replace(i, false); getButtonStatusLocal().fill(false); m_sensor_status.fill(false); } QBitArray &InputDeviceBitArrayStatus::getButtonStatusLocal() { return buttonStatus; } AntiMicroX-antimicrox-b300273/src/inputdevicebitarraystatus.h000066400000000000000000000031501471077622000244320ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef INPUTDEVICESTATUSEVENT_H #define INPUTDEVICESTATUSEVENT_H #include #include #include class InputDevice; class InputDeviceBitArrayStatus : public QObject { Q_OBJECT public: explicit InputDeviceBitArrayStatus(InputDevice *device, bool readCurrent, QObject *parent); void changeAxesStatus(int axisIndex, bool value); void changeButtonStatus(int buttonIndex, bool value); void changeHatStatus(int hatIndex, bool value); void changeSensorStatus(int sensorIndex, bool value); QBitArray generateFinalBitArray(); void clearStatusValues(); private: QBitArray &getButtonStatusLocal(); QList axesStatus; QList hatButtonStatus; QBitArray buttonStatus; QBitArray m_sensor_status; }; #endif // INPUTDEVICESTATUSEVENT_H AntiMicroX-antimicrox-b300273/src/inputdevicecalibration.cpp000066400000000000000000000237301471077622000242010ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "inputdevicecalibration.h" #include "inputdevice.h" #include #include /** * @brief Returns true if the two CalibrationData structs references the same physical, * e.g. stick or sensor input on any controller. Otherwise, it returns false. */ bool CalibrationData::referencesSameInput(const CalibrationData &rhs) const { if (type != rhs.type) return false; if (type == CALIBRATION_DATA_STICK) return stick.index == rhs.stick.index; else if (type == CALIBRATION_DATA_ACCELEROMETER) return true; else if (type == CALIBRATION_DATA_GYROSCOPE) return true; else return false; } InputDeviceCalibration::InputDeviceCalibration(InputDevice *device) : m_device(device) { } /** * @brief Updates the stored calibration for the given stick from the parent controller. * @param[in] index Stick index * @param[in] offsetX Offset value for X axis * @param[in] gainX Gain value for X axis * @param[in] offsetY Offset value for Y axis * @param[in] gainY Gain value for Y axis */ void InputDeviceCalibration::setStickCalibration(int index, double offsetX, double gainX, double offsetY, double gainY) { CalibrationData calibration; calibration.type = CALIBRATION_DATA_STICK; StickCalibrationData &stick = calibration.stick; stick.index = index; stick.offsetX = offsetX; stick.gainX = gainX; stick.offsetY = offsetY; stick.gainY = gainY; setCalibration(m_device->getUniqueIDString(), calibration); } /** * @brief Updates the stored calibration for the given accelerometer from the parent controller. * @param[in] orientationX X coordinate of the neutral orientation vector * @param[in] orientationY Y coordinate of the neutral orientation vector * @param[in] orientationZ Z coordinate of the neutral orientation vector */ void InputDeviceCalibration::setAccelerometerCalibration(double orientationX, double orientationY, double orientationZ) { CalibrationData calibration; calibration.type = CALIBRATION_DATA_ACCELEROMETER; AccelerometerCalibrationData &accelerometer = calibration.accelerometer; accelerometer.orientationX = orientationX; accelerometer.orientationY = orientationY; accelerometer.orientationZ = orientationZ; setCalibration(m_device->getUniqueIDString(), calibration); } /** * @brief Updates the stored calibration for the given gyroscope from the parent controller. * @param[in] offsetX Offset value for X axis * @param[in] offsetY Offset value for Y axis * @param[in] offsetZ Offset value for Z axis */ void InputDeviceCalibration::setGyroscopeCalibration(double offsetX, double offsetY, double offsetZ) { CalibrationData calibration; calibration.type = CALIBRATION_DATA_GYROSCOPE; GyroscopeCalibrationData &gyroscope = calibration.gyroscope; gyroscope.offsetX = offsetX; gyroscope.offsetY = offsetY; gyroscope.offsetZ = offsetZ; setCalibration(m_device->getUniqueIDString(), calibration); } /** * @brief Applies all applicable stored calibration values to the individual * input elements of the parent controller */ void InputDeviceCalibration::applyCalibrations() const { QString id = m_device->getUniqueIDString(); for (const auto &calibration : m_data[id]) { if (calibration.type == CALIBRATION_DATA_STICK) { const StickCalibrationData &data = calibration.stick; m_device->applyStickCalibration(data.index, data.offsetX, data.gainX, data.offsetY, data.gainY); } else if (calibration.type == CALIBRATION_DATA_ACCELEROMETER) { const AccelerometerCalibrationData &data = calibration.accelerometer; m_device->applyAccelerometerCalibration(data.orientationX, data.orientationY, data.orientationZ); } else if (calibration.type == CALIBRATION_DATA_GYROSCOPE) { const GyroscopeCalibrationData &data = calibration.gyroscope; m_device->applyGyroscopeCalibration(data.offsetX, data.offsetY, data.offsetZ); } } } /** * @brief Reads all calibration values from the given XML stream into the internal calibration data storage * @param QXmlStreamReader instance that will be used to read calibration values. */ void InputDeviceCalibration::readConfig(QXmlStreamReader *xml) { while (xml->isStartElement() && (xml->name().toString() == "calibration")) { QString id = xml->attributes().value("device").toString(); if (id.isEmpty()) id = m_device->getUniqueIDString(); xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != "calibration"))) { CalibrationData calibration; if ((xml->name().toString() == "stick")) { calibration.type = CALIBRATION_DATA_STICK; calibration.stick.index = xml->attributes().value("index").toString().toInt(); calibration.stick.offsetX = xml->attributes().value("offsetx").toString().toDouble(); calibration.stick.gainX = xml->attributes().value("gainx").toString().toDouble(); calibration.stick.offsetY = xml->attributes().value("offsety").toString().toDouble(); calibration.stick.gainY = xml->attributes().value("gainy").toString().toDouble(); setCalibration(id, calibration); } else if ((xml->name().toString() == "accelerometer")) { calibration.type = CALIBRATION_DATA_ACCELEROMETER; calibration.accelerometer.orientationX = xml->attributes().value("orientationx").toString().toDouble(); calibration.accelerometer.orientationY = xml->attributes().value("orientationy").toString().toDouble(); calibration.accelerometer.orientationZ = xml->attributes().value("orientationz").toString().toDouble(); setCalibration(id, calibration); } else if ((xml->name().toString() == "gyroscope")) { calibration.type = CALIBRATION_DATA_GYROSCOPE; calibration.gyroscope.offsetX = xml->attributes().value("offsetx").toString().toDouble(); calibration.gyroscope.offsetY = xml->attributes().value("offsety").toString().toDouble(); calibration.gyroscope.offsetZ = xml->attributes().value("offsetz").toString().toDouble(); setCalibration(id, calibration); } xml->skipCurrentElement(); xml->readNextStartElement(); } } } /** * @brief Writes all stored calibration values from the internal storage into the given XML stream. * @param QXmlStreamWriter instance that will be used to write calibration values. */ void InputDeviceCalibration::writeConfig(QXmlStreamWriter *xml) const { for (auto device = m_data.cbegin(); device != m_data.cend(); ++device) { xml->writeStartElement("calibration"); xml->writeAttribute("device", device.key()); for (const auto calibration : *device) { if (calibration.type == CALIBRATION_DATA_STICK) { const StickCalibrationData &data = calibration.stick; xml->writeStartElement("stick"); xml->writeAttribute("index", QString::number(data.index)); xml->writeAttribute("offsetx", QString::number(data.offsetX)); xml->writeAttribute("gainx", QString::number(data.gainX)); xml->writeAttribute("offsety", QString::number(data.offsetY)); xml->writeAttribute("gainy", QString::number(data.gainY)); xml->writeEndElement(); } else if (calibration.type == CALIBRATION_DATA_ACCELEROMETER) { const AccelerometerCalibrationData &data = calibration.accelerometer; xml->writeStartElement("accelerometer"); xml->writeAttribute("orientationx", QString::number(data.orientationX)); xml->writeAttribute("orientationy", QString::number(data.orientationY)); xml->writeAttribute("orientationz", QString::number(data.orientationZ)); xml->writeEndElement(); } else if (calibration.type == CALIBRATION_DATA_GYROSCOPE) { const GyroscopeCalibrationData &data = calibration.gyroscope; xml->writeStartElement("gyroscope"); xml->writeAttribute("offsetx", QString::number(data.offsetX)); xml->writeAttribute("offsety", QString::number(data.offsetY)); xml->writeAttribute("offsetz", QString::number(data.offsetZ)); xml->writeEndElement(); } } xml->writeEndElement(); } } /** * @brief Updated the given CalibrationData structure of the controller with * the given ID in the calibration storage backend. * @param[in] id ID of the device to which the calibration data belongs to * @param[in] new_calibration The CalibrationData structure to be stored */ void InputDeviceCalibration::setCalibration(QString id, CalibrationData new_calibration) { for (auto &calibration : m_data[id]) { if (calibration.referencesSameInput(new_calibration)) { calibration = new_calibration; return; } } m_data[id].append(new_calibration); } AntiMicroX-antimicrox-b300273/src/inputdevicecalibration.h000066400000000000000000000052411471077622000236430ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include class InputDevice; class QXmlStreamReader; class QXmlStreamWriter; /** * @brief Defines the possible CalibrationData union types */ enum CalibrationDataType { CALIBRATION_DATA_STICK, CALIBRATION_DATA_ACCELEROMETER, CALIBRATION_DATA_GYROSCOPE }; /** * @brief The calibration data for a stick */ struct StickCalibrationData { int index; double offsetX; double gainX; double offsetY; double gainY; }; /** * @brief The calibration data for an accelerometer */ struct AccelerometerCalibrationData { double orientationX; double orientationY; double orientationZ; }; /** * @brief The calibration data for a gyroscope */ struct GyroscopeCalibrationData { double offsetX; double offsetY; double offsetZ; }; /** * @brief Stores the calibration data for one physical device, e.g. a stick or gyroscope. */ struct CalibrationData { CalibrationDataType type; union { StickCalibrationData stick; AccelerometerCalibrationData accelerometer; GyroscopeCalibrationData gyroscope; }; bool referencesSameInput(const CalibrationData &rhs) const; }; /** * @brief Calibration storage backend which can store multiple calibration items for different controllers. */ class InputDeviceCalibration { public: explicit InputDeviceCalibration(InputDevice *device); void setStickCalibration(int index, double offsetX, double gainX, double offsetY, double gainY); void setAccelerometerCalibration(double orientationX, double orientationY, double orientationZ); void setGyroscopeCalibration(double offsetX, double offsetY, double offsetZ); void applyCalibrations() const; void readConfig(QXmlStreamReader *xml); void writeConfig(QXmlStreamWriter *xml) const; private: void setCalibration(QString id, CalibrationData new_calibration); QHash> m_data; InputDevice *m_device; }; AntiMicroX-antimicrox-b300273/src/joyaccelerometersensor.cpp000066400000000000000000000200211471077622000242260ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define _USE_MATH_DEFINES #include "joyaccelerometersensor.h" #include "globalvariables.h" #include "joybuttontypes/joyaccelerometerbutton.h" #include const double JoyAccelerometerSensor::SHOCK_DETECT_THRESHOLD = 20.0; const double JoyAccelerometerSensor::SHOCK_SUPPRESS_FACTOR = 0.5; const double JoyAccelerometerSensor::SHOCK_TAU = 0.05; JoyAccelerometerSensor::JoyAccelerometerSensor(double rate, int originset, SetJoystick *parent_set, QObject *parent) : JoySensor(ACCELEROMETER, originset, parent_set, parent) , m_shock_filter(SHOCK_TAU, rate) { reset(); populateButtons(); m_rate = qFuzzyIsNull(rate) ? PT1Filter::FALLBACK_RATE : rate; } JoyAccelerometerSensor::~JoyAccelerometerSensor() {} /** * @brief Get the value for the corresponding X axis. * @return X axis value in m/s^2 */ float JoyAccelerometerSensor::getXCoordinate() const { return m_current_value[0]; } /** * @brief Get the value for the corresponding Y axis. * @return Y axis value in m/s^2 */ float JoyAccelerometerSensor::getYCoordinate() const { return m_current_value[1]; } /** * @brief Get the value for the corresponding Z axis. * @return Z axis value in m/s^2 */ float JoyAccelerometerSensor::getZCoordinate() const { return m_current_value[2]; } /** * @brief Get the translated sensor type name * @returns Translated sensor type name */ QString JoyAccelerometerSensor::sensorTypeName() const { return tr("Accelerometer"); } /** * @brief Reads the calibration values of the sensor * @param[out] offsetX Offset angle around the X axis * @param[out] offsetY Offset angle around the Y axis * @param[out] offsetZ Offset angle around the Z axis */ void JoyAccelerometerSensor::getCalibration(double *offsetX, double *offsetY, double *offsetZ) const { *offsetX = m_calibration_value[0]; *offsetY = m_calibration_value[1]; *offsetZ = m_calibration_value[2]; } /** * @brief Sets the sensor calibration values and sets the calibration flag. * @param[in] offsetX Offset angle around the X axis * @param[in] offsetY Offset angle around the Y axis * @param[in] offsetZ Offset angle around the Z axis * * This stores the orientation vector to store the calibration data later and * calculates the neutral position rotation matrix from the orientation * vector. */ void JoyAccelerometerSensor::setCalibration(double offsetX, double offsetY, double offsetZ) { m_calibration_value[0] = offsetX; m_calibration_value[1] = offsetY; m_calibration_value[2] = offsetZ; double rad = sqrt(offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ); double syz = sqrt(offsetY * offsetY + offsetZ * offsetZ); m_calibration_matrix[0][0] = syz / rad; m_calibration_matrix[0][1] = -offsetX * offsetY / syz / rad; m_calibration_matrix[0][2] = -offsetX * offsetZ / syz / rad; m_calibration_matrix[1][0] = 0; m_calibration_matrix[1][1] = -offsetZ / syz; m_calibration_matrix[1][2] = offsetY / syz; m_calibration_matrix[2][0] = -offsetX / rad; m_calibration_matrix[2][1] = -offsetY / rad; m_calibration_matrix[2][2] = -offsetZ / rad; m_calibrated = true; } /** * @brief Resets internal variables back to default */ void JoyAccelerometerSensor::reset() { JoySensor::reset(); m_max_zone = degToRad(GlobalVariables::JoySensor::ACCEL_MAX); m_shock_filter.reset(); m_shock_suppress_count = 0; } /** * @brief Initializes the JoySensorButton objects for this sensor. */ void JoyAccelerometerSensor::populateButtons() { JoySensorButton *button = nullptr; button = new JoyAccelerometerButton(this, SENSOR_LEFT, m_originset, getParentSet(), this); m_buttons.insert(SENSOR_LEFT, button); button = new JoyAccelerometerButton(this, SENSOR_RIGHT, m_originset, getParentSet(), this); m_buttons.insert(SENSOR_RIGHT, button); button = new JoyAccelerometerButton(this, SENSOR_UP, m_originset, getParentSet(), this); m_buttons.insert(SENSOR_UP, button); button = new JoyAccelerometerButton(this, SENSOR_DOWN, m_originset, getParentSet(), this); m_buttons.insert(SENSOR_DOWN, button); button = new JoyAccelerometerButton(this, SENSOR_BWD, m_originset, getParentSet(), this); m_buttons.insert(SENSOR_BWD, button); } /** * @brief Find the direction zone of the current sensor position. * * First, the pitch and roll angles on the unit sphere are calculated. * Then, the unit sphere is divided into direction zones with the following algorithm: * - Mark a spherical layer around the X axis at +/- the diagonal zone angle * divided by two (called "range" in the code) * - Generate another spherical layers by rotating the first layer around the Y axis. * A third layer is not necessary because there are only two degrees of freedom. * Check if a point is within each layer by comparing the absolute values * of pitch and roll angles against the "range". * If a point is in only one layer, it is in the orthogonal zone of one axis. * If a point is in both or no zones, it is diagonal to both axes. * There are two cases here because the spherical layers overlap if the diagonal * angle is larger then 45 degree. * * Perform shock detection by taking the first order lag filtered absolute sum of * all axes from "joyEvent" and apply a threshold. Discard some samples after * the shock is over to avoid spurious pitch/roll events. * * @returns JoySensorDirection bitfield for the current direction zone. */ JoySensorDirection JoyAccelerometerSensor::calculateSensorDirection() { double abs_sum = abs(m_current_value[0]) + abs(m_current_value[1]) + abs(m_current_value[2]); if (m_shock_filter.process(abs_sum) > SHOCK_DETECT_THRESHOLD) { m_shock_suppress_count = m_rate * SHOCK_SUPPRESS_FACTOR; return SENSOR_BWD; } else if (m_shock_suppress_count != 0) { --m_shock_suppress_count; return SENSOR_CENTERED; } double pitch = calculatePitch(); double roll = calculateRoll(); double pitch_abs = abs(pitch); double roll_abs = abs(roll); double range = M_PI / 4 - m_diagonal_range / 2; bool inPitch = pitch_abs < m_dead_zone; bool inRoll = roll_abs < range; if (isnan(roll)) { return SENSOR_CENTERED; } if (!inPitch) { if (!inRoll) { if (roll > 0) { return pitch > 0 ? SENSOR_LEFT_UP : SENSOR_LEFT_DOWN; } else { return pitch > 0 ? SENSOR_RIGHT_UP : SENSOR_RIGHT_DOWN; } } else { return pitch > 0 ? SENSOR_UP : SENSOR_DOWN; } } else if (!inRoll) { return roll > 0 ? SENSOR_LEFT : SENSOR_RIGHT; } return SENSOR_CENTERED; } /** * @brief Applies calibration to queued input values * * This rotates the sensor coordinate system with the precalculated neutral * position rotation matrix. */ void JoyAccelerometerSensor::applyCalibration() { double x = m_pending_value[0]; double y = m_pending_value[1]; double z = m_pending_value[2]; m_pending_value[0] = m_calibration_matrix[0][0] * x + m_calibration_matrix[0][1] * y + m_calibration_matrix[0][2] * z; m_pending_value[1] = m_calibration_matrix[1][0] * x + m_calibration_matrix[1][1] * y + m_calibration_matrix[1][2] * z; m_pending_value[2] = m_calibration_matrix[2][0] * x + m_calibration_matrix[2][1] * y + m_calibration_matrix[2][2] * z; } AntiMicroX-antimicrox-b300273/src/joyaccelerometersensor.h000066400000000000000000000036331471077622000237050ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "joysensor.h" class SetJoystick; /** * @brief Represents an accelerometer sensor. */ class JoyAccelerometerSensor : public JoySensor { public: explicit JoyAccelerometerSensor(double rate, int originset, SetJoystick *parent_set, QObject *parent); virtual ~JoyAccelerometerSensor(); virtual float getXCoordinate() const override; virtual float getYCoordinate() const override; virtual float getZCoordinate() const override; virtual QString sensorTypeName() const override; virtual void getCalibration(double *offsetX, double *offsetY, double *offsetZ) const override; virtual void setCalibration(double offsetX, double offsetY, double offsetZ) override; public slots: virtual void reset() override; protected: static const double SHOCK_DETECT_THRESHOLD; static const double SHOCK_SUPPRESS_FACTOR; static const double SHOCK_TAU; virtual void populateButtons() override; virtual JoySensorDirection calculateSensorDirection() override; virtual void applyCalibration() override; double m_rate; PT1Filter m_shock_filter; size_t m_shock_suppress_count; double m_calibration_matrix[3][3]; }; AntiMicroX-antimicrox-b300273/src/joyaxis.cpp000066400000000000000000000617451471077622000211500ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joyaxis.h" #include "event.h" #include "globalvariables.h" #include "inputdevice.h" #include "joyaxis.h" #include "joycontrolstick.h" #include "setjoystick.h" #include #include #include #include #include #include const JoyAxis::ThrottleTypes JoyAxis::DEFAULTTHROTTLE = JoyAxis::NormalThrottle; JoyAxis::JoyAxis(int index, int originset, SetJoystick *parentSet, QObject *parent) : QObject(parent) { m_stick = nullptr; lastKnownThottledValue = 0; lastKnownRawValue = 0; currentRawValue = 0; m_originset = originset; m_parentSet = parentSet; naxisbutton = new JoyAxisButton(this, 0, originset, parentSet, this); paxisbutton = new JoyAxisButton(this, 1, originset, parentSet, this); resetPrivateVars(); m_index = index; } JoyAxis::~JoyAxis() { resetPrivateVars(); } void JoyAxis::queuePendingEvent(int value, bool ignoresets, bool updateLastValues) { if (m_calibrated) value = value * m_gain + m_offset; if (m_stick != nullptr) { pendingEvent = false; pendingValue = 0; pendingIgnoreSets = false; stickPassEvent(value, ignoresets, updateLastValues); } else { pendingEvent = true; pendingValue = value; pendingIgnoreSets = ignoresets; } } void JoyAxis::activatePendingEvent() { if (pendingEvent) { joyEvent(pendingValue, pendingIgnoreSets); pendingEvent = false; pendingValue = false; pendingIgnoreSets = false; } } bool JoyAxis::hasPendingEvent() { return pendingEvent; } void JoyAxis::clearPendingEvent() { pendingEvent = false; pendingValue = false; pendingIgnoreSets = false; } void JoyAxis::stickPassEvent(int value, bool ignoresets, bool updateLastValues) { if (m_stick != nullptr) { if (updateLastValues) { lastKnownThottledValue = currentThrottledValue; lastKnownRawValue = currentRawValue; } setCurrentRawValue(value); bool safezone = !inDeadZone(currentRawValue); currentThrottledValue = calculateThrottledValue(value); if (safezone && !isActive) { isActive = eventActive = true; emit active(value); } else if (!safezone && isActive) { isActive = eventActive = false; emit released(value); } if (!ignoresets) m_stick->queueJoyEvent(ignoresets); else m_stick->joyEvent(ignoresets); emit moved(currentRawValue); } } void JoyAxis::joyEvent(int value, bool ignoresets, bool updateLastValues) { if ((m_stick != nullptr) && !pendingEvent) { stickPassEvent(value, ignoresets, updateLastValues); } else { if (updateLastValues) { lastKnownThottledValue = currentThrottledValue; lastKnownRawValue = currentRawValue; } setCurrentRawValue(value); bool safezone = !inDeadZone(currentRawValue); currentThrottledValue = calculateThrottledValue(value); // If in joystick mode and this is the first detected event, // use the current value as the axis center point. If the value // is below -30,000 then consider it a trigger. InputDevice *device = m_parentSet->getInputDevice(); if (!device->isGameController() && !device->hasCalibrationThrottle(m_index)) { performCalibration(currentRawValue); safezone = !inDeadZone(currentRawValue); currentThrottledValue = calculateThrottledValue(value); } if (safezone && !isActive) { isActive = eventActive = true; emit active(value); createDeskEvent(ignoresets); } else if (!safezone && isActive) { isActive = eventActive = false; emit released(value); createDeskEvent(ignoresets); } else if (isActive) { createDeskEvent(ignoresets); } } emit moved(currentRawValue); } bool JoyAxis::inDeadZone(int value) { bool result = false; int temp = calculateThrottledValue(value); if (abs(temp) <= deadZone) { // qDebug() << "Value of throttle is in (less than) dead zone: " << abs(temp) << " <= " << deadZone; result = true; } else { // qDebug() << "Value of throttle is not in (greater than) dead zone: " << abs(temp) << " > " << deadZone; } return result; } QString JoyAxis::getName(bool forceFullFormat, bool displayNames) { QString label = getPartialName(forceFullFormat, displayNames); label.append(": "); if (throttle == static_cast(NormalThrottle)) { label.append("-"); if (!naxisbutton->getActionName().isEmpty() && displayNames) { label.append(naxisbutton->getActionName()); } else { label.append(naxisbutton->getCalculatedActiveZoneSummary()); } label.append(" | +"); if (!paxisbutton->getActionName().isEmpty() && displayNames) { label.append(paxisbutton->getActionName()); } else { label.append(paxisbutton->getCalculatedActiveZoneSummary()); } } else if ((throttle == static_cast(PositiveThrottle)) || (throttle == static_cast(PositiveHalfThrottle))) { label.append("+"); if (!paxisbutton->getActionName().isEmpty() && displayNames) { label.append(paxisbutton->getActionName()); } else { label.append(paxisbutton->getCalculatedActiveZoneSummary()); } } else if ((throttle == static_cast(NegativeThrottle)) || (throttle == static_cast(NegativeHalfThrottle))) { label.append("-"); if (!naxisbutton->getActionName().isEmpty() && displayNames) { label.append(naxisbutton->getActionName()); } else { label.append(naxisbutton->getCalculatedActiveZoneSummary()); } } return label; } int JoyAxis::getRealJoyIndex() { return m_index + 1; } int JoyAxis::getCurrentThrottledValue() { return currentThrottledValue; } void JoyAxis::updateCurrentThrottledValue(int newValue) { currentThrottledValue = newValue; } int JoyAxis::calculateThrottledValue(int value) { // QScopedPointer log(new DEBUG()); // *log << "Throttled value at start of function is: " << value; int temp = value; switch (throttle) { case -2: // *log << ". It's a negative half throttle."; value = (value <= 0) ? value : -value; temp = value; break; case -1: // *log << ". It's a negative throttle."; temp = (value + GlobalVariables::JoyAxis::AXISMIN) / 2; break; case 1: // *log << ". It's a positive throttle."; temp = (value + GlobalVariables::JoyAxis::AXISMAX) / 2; break; case 2: // *log << ". It's a positive half throttle."; value = (value >= 0) ? value : -value; temp = value; break; } // *log << " Calculated value of throttle is: " << temp; return temp; } /** * @brief Checks if the axis supports haptic trigger feedback. * @returns True if the axis supports haptic trigger feedback, false otherwise. */ bool JoyAxis::hasHapticTrigger() const { return false; } /** * @brief Always returns nullptr for JoyAxis base objects. */ HapticTriggerPs5 *JoyAxis::getHapticTrigger() const { return nullptr; } /** * @brief Changes the haptic trigger effect mode. * @param[in] mode New haptic trigger effect mode. */ void JoyAxis::setHapticTriggerMode(HapticTriggerModePs5) {} void JoyAxis::setIndex(int index) { m_index = index; } int JoyAxis::getIndex() { return m_index; } void JoyAxis::createDeskEvent(bool ignoresets) { JoyAxisButton *eventbutton = nullptr; if (currentThrottledValue > deadZone) eventbutton = paxisbutton; else if (currentThrottledValue < -deadZone) eventbutton = naxisbutton; if ((eventbutton != nullptr) && !activeButton) { // There is no active button. Call joyEvent and set current // button as active button eventbutton->joyEvent(eventActive, ignoresets); activeButton = eventbutton; } else if ((eventbutton == nullptr) && (activeButton != nullptr)) { // Currently in deadzone. Disable currently active button. activeButton->joyEvent(eventActive, ignoresets); activeButton = nullptr; } else if ((eventbutton != nullptr) && (activeButton != nullptr) && (eventbutton == activeButton)) { // Button is currently active. Just pass current value eventbutton->joyEvent(eventActive, ignoresets); } else if ((eventbutton != nullptr) && (activeButton != nullptr) && (eventbutton != activeButton)) { // Deadzone skipped. Button for new event is not the currently // active button. Disable the active button before enabling // the new button activeButton->joyEvent(!eventActive, ignoresets); eventbutton->joyEvent(eventActive, ignoresets); activeButton = eventbutton; } } void JoyAxis::setDeadZone(int value) { value = abs(value); if (deadZone == value) return; deadZone = value; emit propertyUpdated(); emit hapticTriggerChanged(); } int JoyAxis::getDeadZone() { return deadZone; } void JoyAxis::setMaxZoneValue(int value) { value = abs(value); if (value >= GlobalVariables::JoyAxis::AXISMAX) { maxZoneValue = GlobalVariables::JoyAxis::AXISMAX; emit propertyUpdated(); } else { maxZoneValue = value; emit propertyUpdated(); } } int JoyAxis::getMaxZoneValue() { return maxZoneValue; } /** * @brief Set throttle value for axis. * @param Current value for axis. */ void JoyAxis::setThrottle(int value) { qDebug() << "Value of throttle for axis in setThrottle is: " << value; if ((value >= static_cast(JoyAxis::NegativeHalfThrottle)) && (value <= static_cast(JoyAxis::PositiveHalfThrottle))) { if (value != throttle) { qDebug() << "Throttle value for variable \"throttle\" has been set: " << value; throttle = value; adjustRange(); emit throttleChanged(); emit propertyUpdated(); } } } /** * @brief Set the initial calibrated throttle based on the first event * passed by SDL. * @param Current value for axis. */ void JoyAxis::setInitialThrottle(int value) { if ((value >= static_cast(JoyAxis::NegativeHalfThrottle)) && (value <= static_cast(JoyAxis::PositiveHalfThrottle)) && (value != throttle)) { throttle = value; adjustRange(); emit throttleChanged(); } } int JoyAxis::getThrottle() { return throttle; } void JoyAxis::reset() { resetPrivateVars(); } void JoyAxis::resetPrivateVars() { deadZone = GlobalVariables::JoyAxis::AXISDEADZONE; isActive = false; eventActive = false; maxZoneValue = GlobalVariables::JoyAxis::AXISMAXZONE; throttle = this->DEFAULTTHROTTLE; paxisbutton->reset(); naxisbutton->reset(); activeButton = nullptr; lastKnownThottledValue = 0; lastKnownRawValue = 0; adjustRange(); setCurrentRawValue(currentThrottledDeadValue); currentThrottledValue = calculateThrottledValue(currentRawValue); axisName.clear(); m_calibrated = false; pendingEvent = false; pendingValue = currentRawValue; pendingIgnoreSets = false; } void JoyAxis::reset(int index) { reset(); m_index = index; } JoyAxisButton *JoyAxis::getPAxisButton() { return paxisbutton; } JoyAxisButton *JoyAxis::getNAxisButton() { return naxisbutton; } int JoyAxis::getCurrentRawValue() { return currentRawValue; } void JoyAxis::adjustRange() { if (throttle == static_cast(JoyAxis::NegativeThrottle)) { currentThrottledDeadValue = GlobalVariables::JoyAxis::AXISMAX; } else if ((throttle == static_cast(JoyAxis::NormalThrottle)) || (throttle == static_cast(JoyAxis::PositiveHalfThrottle)) || (throttle == static_cast(JoyAxis::NegativeHalfThrottle))) { currentThrottledDeadValue = 0; } else if (throttle == static_cast(JoyAxis::PositiveThrottle)) { currentThrottledDeadValue = GlobalVariables::JoyAxis::AXISMIN; } currentThrottledValue = calculateThrottledValue(currentRawValue); } int JoyAxis::getCurrentThrottledDeadValue() { return currentThrottledDeadValue; } double JoyAxis::getDistanceFromDeadZone() { return getDistanceFromDeadZone(currentThrottledValue); } double JoyAxis::getDistanceFromDeadZone(int value) { double distance = 0.0; if (value >= deadZone) { distance = static_cast(value - deadZone) / (maxZoneValue - deadZone); } else if (value <= -deadZone) { distance = static_cast(value + deadZone) / ((-maxZoneValue) + deadZone); } return qBound(0.0, distance, 1.0); } /** * @brief Get the current value for an axis in either direction converted to * the range of -1.0 to 1.0. * @param Current interger value of the axis * @return Axis value in the range of -1.0 to 1.0 */ double JoyAxis::getRawDistance(int value) { return qBound(-1.0, static_cast(value) / maxZoneValue, 1.0); } void JoyAxis::propogateThrottleChange() { emit throttleChangePropogated(m_index); } int JoyAxis::getCurrentlyAssignedSet() { return m_originset; } void JoyAxis::setControlStick(JoyControlStick *stick) { removeVDPads(); removeControlStick(); m_stick = stick; emit propertyUpdated(); } bool JoyAxis::isPartControlStick() { return (m_stick != nullptr); } JoyControlStick *JoyAxis::getControlStick() { return m_stick; } void JoyAxis::removeControlStick(bool performRelease) { if (m_stick != nullptr) { if (performRelease) m_stick->releaseButtonEvents(); m_stick = nullptr; // emit propertyUpdated(); } } bool JoyAxis::hasControlOfButtons() { bool value = true; if (paxisbutton->isPartVDPad() || naxisbutton->isPartVDPad()) { value = false; } return value; } void JoyAxis::removeVDPads() { if (paxisbutton->isPartVDPad()) { paxisbutton->joyEvent(false, true); paxisbutton->removeVDPad(); } if (naxisbutton->isPartVDPad()) { naxisbutton->joyEvent(false, true); naxisbutton->removeVDPad(); } } bool JoyAxis::isDefault() { bool value = true; value = value && (deadZone == getDefaultDeadZone()); value = value && (maxZoneValue == getDefaultMaxZone()); value = value && (paxisbutton->isDefault()); value = value && (naxisbutton->isDefault()); return value; } /* Use this method to keep currentRawValue in the expected range. * SDL has a minimum axis value of -32768 which should be ignored to * ensure that JoyControlStick will not encounter overflow problems * on a 32 bit machine. */ void JoyAxis::setCurrentRawValue(int value) { currentRawValue = qBound(GlobalVariables::JoyAxis::AXISMIN, value, GlobalVariables::JoyAxis::AXISMAX); } void JoyAxis::setButtonsMouseMode(JoyButton::JoyMouseMovementMode mode) { paxisbutton->setMouseMode(mode); naxisbutton->setMouseMode(mode); } bool JoyAxis::hasSameButtonsMouseMode() { bool result = true; if (paxisbutton->getMouseMode() != naxisbutton->getMouseMode()) { result = false; } return result; } JoyButton::JoyMouseMovementMode JoyAxis::getButtonsPresetMouseMode() { JoyButton::JoyMouseMovementMode resultMode = JoyButton::MouseCursor; if (paxisbutton->getMouseMode() == naxisbutton->getMouseMode()) resultMode = paxisbutton->getMouseMode(); return resultMode; } void JoyAxis::setButtonsMouseCurve(JoyButton::JoyMouseCurve mouseCurve) { paxisbutton->setMouseCurve(mouseCurve); naxisbutton->setMouseCurve(mouseCurve); } bool JoyAxis::hasSameButtonsMouseCurve() { bool result = true; if (paxisbutton->getMouseCurve() != naxisbutton->getMouseCurve()) { result = false; } return result; } JoyButton::JoyMouseCurve JoyAxis::getButtonsPresetMouseCurve() { JoyButton::JoyMouseCurve resultCurve = JoyButton::LinearCurve; if (paxisbutton->getMouseCurve() == naxisbutton->getMouseCurve()) { resultCurve = paxisbutton->getMouseCurve(); } return resultCurve; } void JoyAxis::setButtonsSpringWidth(int value) { paxisbutton->setSpringWidth(value); naxisbutton->setSpringWidth(value); } void JoyAxis::setButtonsSpringHeight(int value) { paxisbutton->setSpringHeight(value); naxisbutton->setSpringHeight(value); } int JoyAxis::getButtonsPresetSpringWidth() { int presetSpringWidth = 0; if (paxisbutton->getSpringWidth() == naxisbutton->getSpringWidth()) presetSpringWidth = paxisbutton->getSpringWidth(); return presetSpringWidth; } int JoyAxis::getButtonsPresetSpringHeight() { int presetSpringHeight = 0; if (paxisbutton->getSpringHeight() == naxisbutton->getSpringHeight()) presetSpringHeight = paxisbutton->getSpringHeight(); return presetSpringHeight; } void JoyAxis::setButtonsSensitivity(double value) { paxisbutton->setSensitivity(value); naxisbutton->setSensitivity(value); } double JoyAxis::getButtonsPresetSensitivity() { double presetSensitivity = 1.0; if (qFuzzyCompare(paxisbutton->getSensitivity(), naxisbutton->getSensitivity())) presetSensitivity = paxisbutton->getSensitivity(); return presetSensitivity; } JoyAxisButton *JoyAxis::getAxisButtonByValue(int value) { JoyAxisButton *eventbutton = nullptr; int throttledValue = calculateThrottledValue(value); qDebug() << "throttledValue in getAxisButtonByValue is: " << throttledValue; if (throttledValue > deadZone) { qDebug() << "throtted value is positive"; eventbutton = paxisbutton; } else if (throttledValue < (-deadZone)) { qDebug() << "throtted value is negative"; eventbutton = naxisbutton; } return eventbutton; } void JoyAxis::setAxisName(QString tempName) { if ((tempName.length() <= 20) && (tempName != axisName)) { axisName = tempName; emit axisNameChanged(); emit propertyUpdated(); } } QString JoyAxis::getAxisName() { return axisName; } void JoyAxis::setButtonsWheelSpeedX(int value) { paxisbutton->setWheelSpeed(value, 'X'); naxisbutton->setWheelSpeed(value, 'X'); } void JoyAxis::setButtonsWheelSpeedY(int value) { paxisbutton->setWheelSpeed(value, 'Y'); naxisbutton->setWheelSpeed(value, 'Y'); } void JoyAxis::setDefaultAxisName(QString tempname) { defaultAxisName = tempname; } QString JoyAxis::getDefaultAxisName() { return defaultAxisName; } QString JoyAxis::getPartialName(bool forceFullFormat, bool displayNames) { QString label = QString(); if (!axisName.isEmpty() && displayNames) { if (forceFullFormat) { label.append(tr("Axis")).append(" "); } label.append(axisName); } else if (!defaultAxisName.isEmpty()) { if (forceFullFormat) { label.append(tr("Axis")).append(" "); } label.append(defaultAxisName); } else { label.append(tr("Axis")).append(" "); label.append(QString::number(getRealJoyIndex())); } return label; } QString JoyAxis::getXmlName() { return GlobalVariables::JoyAxis::xmlName; } int JoyAxis::getDefaultDeadZone() { return GlobalVariables::JoyAxis::AXISDEADZONE; } int JoyAxis::getDefaultMaxZone() { return GlobalVariables::JoyAxis::AXISMAXZONE; } JoyAxis::ThrottleTypes JoyAxis::getDefaultThrottle() { return this->DEFAULTTHROTTLE; } SetJoystick *JoyAxis::getParentSet() { return m_parentSet; } void JoyAxis::establishPropertyUpdatedConnection() { connect(this, &JoyAxis::propertyUpdated, getParentSet()->getInputDevice(), &InputDevice::profileEdited); } void JoyAxis::disconnectPropertyUpdatedConnection() { disconnect(this, &JoyAxis::propertyUpdated, getParentSet()->getInputDevice(), &InputDevice::profileEdited); } void JoyAxis::setButtonsSpringRelativeStatus(bool value) { paxisbutton->setSpringRelativeStatus(value); naxisbutton->setSpringRelativeStatus(value); } bool JoyAxis::isRelativeSpring() { bool relative = false; if (paxisbutton->isRelativeSpring() == naxisbutton->isRelativeSpring()) relative = paxisbutton->isRelativeSpring(); return relative; } void JoyAxis::performCalibration(int value) { InputDevice *device = m_parentSet->getInputDevice(); if (value <= -30000) { // Assume axis is a trigger. Set default throttle to Positive. device->setCalibrationThrottle(m_index, PositiveThrottle); } else { // Ensure that default throttle is used when a device is reset. device->setCalibrationThrottle(m_index, static_cast(throttle)); } } void JoyAxis::copyAssignments(JoyAxis *destAxis) { destAxis->reset(); destAxis->deadZone = deadZone; destAxis->maxZoneValue = maxZoneValue; destAxis->axisName = axisName; paxisbutton->copyAssignments(destAxis->paxisbutton); naxisbutton->copyAssignments(destAxis->naxisbutton); if (!destAxis->isDefault()) emit propertyUpdated(); } void JoyAxis::setButtonsEasingDuration(double value) { paxisbutton->setEasingDuration(value); naxisbutton->setEasingDuration(value); } double JoyAxis::getButtonsEasingDuration() { double result = GlobalVariables::JoyButton::DEFAULTEASINGDURATION; if (qFuzzyCompare(paxisbutton->getEasingDuration(), naxisbutton->getEasingDuration())) { result = paxisbutton->getEasingDuration(); } return result; } int JoyAxis::getLastKnownThrottleValue() { return lastKnownThottledValue; } int JoyAxis::getLastKnownRawValue() { return lastKnownRawValue; } /** * @brief Determine an appropriate release value for an axis depending * on the current throttle setting being used. * @return Release value for an axis */ int JoyAxis::getProperReleaseValue() { // Handles NormalThrottle case int value = 0; if (throttle == static_cast(NegativeHalfThrottle)) { value = 0; } else if (throttle == static_cast(NegativeThrottle)) { value = GlobalVariables::JoyAxis::AXISMAX; } else if (throttle == static_cast(PositiveThrottle)) { value = GlobalVariables::JoyAxis::AXISMIN; } else if (throttle == static_cast(PositiveHalfThrottle)) { value = 0; } return value; } void JoyAxis::setExtraAccelerationCurve(JoyButton::JoyExtraAccelerationCurve curve) { paxisbutton->setExtraAccelerationCurve(curve); naxisbutton->setExtraAccelerationCurve(curve); } JoyButton::JoyExtraAccelerationCurve JoyAxis::getExtraAccelerationCurve() { JoyButton::JoyExtraAccelerationCurve result = JoyButton::LinearAccelCurve; if (paxisbutton->getExtraAccelerationCurve() == naxisbutton->getExtraAccelerationCurve()) { result = paxisbutton->getExtraAccelerationCurve(); } return result; } void JoyAxis::copyRawValues(JoyAxis *srcAxis) { this->lastKnownRawValue = srcAxis->lastKnownRawValue; this->currentRawValue = srcAxis->currentRawValue; } void JoyAxis::copyThrottledValues(JoyAxis *srcAxis) { this->lastKnownThottledValue = srcAxis->lastKnownThottledValue; this->currentThrottledValue = srcAxis->currentThrottledValue; } void JoyAxis::eventReset() { naxisbutton->eventReset(); paxisbutton->eventReset(); } /** * @brief Check if the axis is calibrated * @returns True if the axis is calibrated, false otherwise. */ bool JoyAxis::isCalibrated() const { return m_calibrated; } /** * @brief Resets the axis calibration back to uncalibrated state. */ void JoyAxis::resetCalibration() { m_calibrated = false; } /** * @brief Reads the axis calibration values * @param[out] offset Offset value "a" * @param[out] gain Gain value "b" */ void JoyAxis::getCalibration(double *offset, double *gain) const { *offset = m_offset; *gain = m_gain; } /** * @brief Sets the axis calibration values and sets the calibration flag. * Calibrated value is calculated by the formula "a+b*x". */ void JoyAxis::setCalibration(double offset, double gain) { m_calibrated = true; m_offset = offset; m_gain = gain; } AntiMicroX-antimicrox-b300273/src/joyaxis.h000066400000000000000000000156741471077622000206150ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYAXIS_H #define JOYAXIS_H #include #include #include "haptictriggermodeps5.h" #include "joybuttontypes/joyaxisbutton.h" class HapticTriggerPs5; class JoyControlStick; class SetJoystick; class JoyAxisButton; class QXmlStreamReader; class QXmlStreamWriter; class JoyAxis; /** * @brief Represents single axis of of joystick (or other input) * */ class JoyAxis : public QObject { Q_OBJECT public: explicit JoyAxis(int index, int originset, SetJoystick *parentSet, QObject *parent); virtual ~JoyAxis(); enum ThrottleTypes { NegativeHalfThrottle = -2, NegativeThrottle = -1, NormalThrottle = 0, PositiveThrottle = 1, PositiveHalfThrottle = 2 }; void joyEvent(int value, bool ignoresets = false, bool updateLastValues = true); // JoyAxisEvent class void queuePendingEvent(int value, bool ignoresets = false, bool updateLastValues = true); // JoyAxisEvent class void activatePendingEvent(); // JoyAxisEvent class bool hasPendingEvent(); // JoyAxisEvent class void clearPendingEvent(); // JoyAxisEvent class bool inDeadZone(int value); virtual QString getName(bool forceFullFormat = false, bool displayNames = false); virtual QString getPartialName(bool forceFullFormat = false, bool displayNames = false); virtual QString getXmlName(); // JoyAxisXml class void setIndex(int index); int getIndex(); int getRealJoyIndex(); JoyAxisButton *getPAxisButton(); JoyAxisButton *getNAxisButton(); int getDeadZone(); int getMaxZoneValue(); void setThrottle(int value); void setInitialThrottle(int value); void updateCurrentThrottledValue(int newValue); int getThrottle(); int getCurrentThrottledValue(); int getCurrentRawValue(); int getCurrentThrottledDeadValue(); int getCurrentlyAssignedSet(); JoyAxisButton *getAxisButtonByValue(int value); double getDistanceFromDeadZone(); double getDistanceFromDeadZone(int value); double getRawDistance(int value); void setControlStick(JoyControlStick *stick); void removeControlStick(bool performRelease = true); bool isPartControlStick(); JoyControlStick *getControlStick(); bool hasControlOfButtons(); void removeVDPads(); void setButtonsMouseMode(JoyButton::JoyMouseMovementMode mode); bool hasSameButtonsMouseMode(); JoyButton::JoyMouseMovementMode getButtonsPresetMouseMode(); void setButtonsMouseCurve(JoyButton::JoyMouseCurve mouseCurve); bool hasSameButtonsMouseCurve(); JoyButton::JoyMouseCurve getButtonsPresetMouseCurve(); void setButtonsSpringWidth(int value); int getButtonsPresetSpringWidth(); void setButtonsSpringHeight(int value); int getButtonsPresetSpringHeight(); void setButtonsSensitivity(double value); double getButtonsPresetSensitivity(); void setButtonsWheelSpeedX(int value); void setButtonsWheelSpeedY(int value); double getButtonsEasingDuration(); bool isCalibrated() const; void resetCalibration(); void getCalibration(double *offset, double *gain) const; void setCalibration(double offset, double gain); virtual QString getAxisName(); virtual int getDefaultDeadZone(); virtual int getDefaultMaxZone(); virtual ThrottleTypes getDefaultThrottle(); virtual void setDefaultAxisName(QString tempname); virtual QString getDefaultAxisName(); SetJoystick *getParentSet(); virtual bool isDefault(); bool isRelativeSpring(); void copyAssignments(JoyAxis *destAxis); int getLastKnownThrottleValue(); int getLastKnownRawValue(); int getProperReleaseValue(); void setCurrentRawValue(int value); // Don't use direct assignment but copying from a current axis. void copyRawValues(JoyAxis *srcAxis); void copyThrottledValues(JoyAxis *srcAxis); void setExtraAccelerationCurve(JoyButton::JoyExtraAccelerationCurve curve); JoyButton::JoyExtraAccelerationCurve getExtraAccelerationCurve(); virtual void eventReset(); // JoyAxisEvent class static const ThrottleTypes DEFAULTTHROTTLE; int calculateThrottledValue(int value); virtual bool hasHapticTrigger() const; virtual HapticTriggerPs5 *getHapticTrigger() const; virtual void setHapticTriggerMode(HapticTriggerModePs5); protected: void createDeskEvent(bool ignoresets = false); // JoyAxisEvent class void adjustRange(); void performCalibration(int value); void stickPassEvent(int value, bool ignoresets = false, bool updateLastValues = true); // JoyAxisEvent class JoyAxisButton *paxisbutton; JoyAxisButton *naxisbutton; QString axisName; QString defaultAxisName; int throttle; int deadZone; int maxZoneValue; int currentRawValue; int currentThrottledValue; int currentThrottledDeadValue; int m_index; int lastKnownThottledValue; int lastKnownRawValue; int pendingValue; bool isActive; bool pendingEvent; bool pendingIgnoreSets; bool eventActive; JoyAxisButton *activeButton; // TODO: CHECK IF PROPERTY IS NEEDED. // bool pendingUpdateLastValues; signals: void active(int value); void released(int value); void moved(int value); void throttleChangePropogated(int index); void throttleChanged(); void axisNameChanged(); void propertyUpdated(); void hapticTriggerChanged(); public slots: virtual void reset(); virtual void reset(int index); void propogateThrottleChange(); void setDeadZone(int value); void setMaxZoneValue(int value); void setAxisName(QString tempName); void setButtonsSpringRelativeStatus(bool value); void setButtonsEasingDuration(double value); void establishPropertyUpdatedConnection(); void disconnectPropertyUpdatedConnection(); private: int m_originset; JoyControlStick *m_stick; SetJoystick *m_parentSet; bool m_calibrated; double m_offset; double m_gain; void resetPrivateVars(); }; #endif // JOYAXIS_H AntiMicroX-antimicrox-b300273/src/joyaxiscontextmenu.cpp000066400000000000000000000440071471077622000234320ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joyaxiscontextmenu.h" #include "antkeymapper.h" #include "common.h" #include "inputdevice.h" #include "joyaxis.h" #include "mousedialog/mouseaxissettingsdialog.h" #include #include #include JoyAxisContextMenu::JoyAxisContextMenu(JoyAxis *axis, QWidget *parent) : QMenu(parent) , helper(axis) { this->axis = axis; getHelperLocal().moveToThread(axis->thread()); connect(this, &JoyAxisContextMenu::aboutToHide, this, &JoyAxisContextMenu::deleteLater); } void JoyAxisContextMenu::buildMenu() { bool actAsTrigger = false; PadderCommon::inputDaemonMutex.lock(); if ((axis->getThrottle() == static_cast(JoyAxis::PositiveThrottle)) || (axis->getThrottle() == static_cast(JoyAxis::PositiveHalfThrottle))) { actAsTrigger = true; } PadderCommon::inputDaemonMutex.unlock(); if (actAsTrigger) buildTriggerMenu(); else buildAxisMenu(); } void JoyAxisContextMenu::buildAxisMenu() { QActionGroup *presetGroup = new QActionGroup(this); int presetMode = 0; int currentPreset = getPresetIndex(); QAction *action = this->addAction(tr("Mouse (Horizontal)")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setAxisPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Mouse (Inverted Horizontal)")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setAxisPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Mouse (Vertical)")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setAxisPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Mouse (Inverted Vertical)")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setAxisPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Arrows: Up | Down")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setAxisPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Arrows: Left | Right")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setAxisPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Keys: W | S")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setAxisPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Keys: A | D")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setAxisPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("NumPad: KP_8 | KP_2")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setAxisPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("NumPad: KP_4 | KP_6")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setAxisPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("None")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setAxisPreset(action); }); presetGroup->addAction(action); this->addSeparator(); action = this->addAction(tr("Mouse Settings")); action->setCheckable(false); connect(action, &QAction::triggered, this, &JoyAxisContextMenu::openMouseSettingsDialog); } int JoyAxisContextMenu::getPresetIndex() { int result = 0; JoyAxisButton *naxisbutton = axis->getNAxisButton(); QList *naxisslots = naxisbutton->getAssignedSlots(); JoyAxisButton *paxisbutton = axis->getPAxisButton(); QList *paxisslots = paxisbutton->getAssignedSlots(); if ((naxisslots->length() == 1) && (paxisslots->length() == 1)) { JoyButtonSlot *nslot = naxisslots->at(0); JoyButtonSlot *pslot = paxisslots->at(0); if ((nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (nslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (pslot->getSlotCode() == JoyButtonSlot::MouseRight)) { result = 1; } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (nslot->getSlotCode() == JoyButtonSlot::MouseRight) && (pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (pslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { result = 2; } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (nslot->getSlotCode() == JoyButtonSlot::MouseUp) && (pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (pslot->getSlotCode() == JoyButtonSlot::MouseDown)) { result = 3; } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (nslot->getSlotCode() == JoyButtonSlot::MouseDown) && (pslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (pslot->getSlotCode() == JoyButtonSlot::MouseUp)) { result = 4; } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down))) { result = 5; } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right))) { result = 6; } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S))) { result = 7; } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D))) { result = 8; } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2))) { result = 9; } else if ((nslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (nslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4)) && (pslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (pslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6))) { result = 10; } } else if ((naxisslots->length() == 0) && (paxisslots->length() == 0)) { result = 11; } PadderCommon::inputDaemonMutex.unlock(); return result; } void JoyAxisContextMenu::setAxisPreset(QAction *action) { int item = action->data().toInt(); JoyButtonSlot *nbuttonslot = nullptr; JoyButtonSlot *pbuttonslot = nullptr; switch (item) { case 0: nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); break; case 1: nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); break; case 2: nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); break; case 3: nbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); break; case 4: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up), Qt::Key_Up, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down), Qt::Key_Down, JoyButtonSlot::JoyKeyboard, this); break; case 5: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left), Qt::Key_Left, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right), Qt::Key_Right, JoyButtonSlot::JoyKeyboard, this); break; case 6: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W), Qt::Key_W, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S), Qt::Key_S, JoyButtonSlot::JoyKeyboard, this); break; case 7: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A), Qt::Key_A, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D), Qt::Key_D, JoyButtonSlot::JoyKeyboard, this); break; case 8: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); break; case 9: nbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); pbuttonslot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); break; case 10: QMetaObject::invokeMethod(&helper, "clearAndResetAxisButtons", Qt::BlockingQueuedConnection); break; } if (nbuttonslot != nullptr) { QMetaObject::invokeMethod(&helper, "setNAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, nbuttonslot->getSlotCode()), Q_ARG(int, nbuttonslot->getSlotCodeAlias()), Q_ARG(JoyButtonSlot::JoySlotInputAction, nbuttonslot->getSlotMode())); nbuttonslot->deleteLater(); } if (pbuttonslot != nullptr) { QMetaObject::invokeMethod(&helper, "setPAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, nbuttonslot->getSlotCode()), Q_ARG(int, nbuttonslot->getSlotCodeAlias()), Q_ARG(JoyButtonSlot::JoySlotInputAction, nbuttonslot->getSlotMode())); pbuttonslot->deleteLater(); } } void JoyAxisContextMenu::openMouseSettingsDialog() { MouseAxisSettingsDialog *dialog = new MouseAxisSettingsDialog(this->axis, parentWidget()); dialog->show(); } void JoyAxisContextMenu::buildTriggerMenu() { QActionGroup *presetGroup = new QActionGroup(this); int presetMode = 0; int currentPreset = getTriggerPresetIndex(); QAction *action = this->addAction(tr("Left Mouse Button")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setTriggerPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Right Mouse Button")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setTriggerPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("None")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action]() { setTriggerPreset(action); }); presetGroup->addAction(action); this->addSeparator(); action = this->addAction(tr("Mouse Settings")); action->setCheckable(false); connect(action, &QAction::triggered, this, &JoyAxisContextMenu::openMouseSettingsDialog); } int JoyAxisContextMenu::getTriggerPresetIndex() { int result = 0; PadderCommon::inputDaemonMutex.lock(); JoyAxisButton *paxisbutton = axis->getPAxisButton(); QList *paxisslots = paxisbutton->getAssignedSlots(); if (paxisslots->length() == 1) { JoyButtonSlot *pslot = paxisslots->at(0); if ((pslot->getSlotMode() == JoyButtonSlot::JoyMouseButton) && (pslot->getSlotCode() == JoyButtonSlot::MouseLB)) { result = 1; } else if ((pslot->getSlotMode() == JoyButtonSlot::JoyMouseButton) && (pslot->getSlotCode() == JoyButtonSlot::MouseRB)) { result = 2; } } else if (paxisslots->length() == 0) { result = 3; } PadderCommon::inputDaemonMutex.unlock(); return result; } void JoyAxisContextMenu::setTriggerPreset(QAction *action) { int item = action->data().toInt(); JoyButtonSlot *pbuttonslot = nullptr; switch (item) { case 0: pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseLB, JoyButtonSlot::JoyMouseButton, this); break; case 1: pbuttonslot = new JoyButtonSlot(JoyButtonSlot::MouseRB, JoyButtonSlot::JoyMouseButton, this); break; case 2: JoyAxisButton *pbutton = axis->getPAxisButton(); QMetaObject::invokeMethod(pbutton, "clearSlotsEventReset", Qt::BlockingQueuedConnection); break; } if (pbuttonslot != nullptr) { QMetaObject::invokeMethod(&helper, "setPAssignedSlot", Qt::BlockingQueuedConnection, Q_ARG(int, pbuttonslot->getSlotCode()), Q_ARG(int, pbuttonslot->getSlotCodeAlias()), Q_ARG(JoyButtonSlot::JoySlotInputAction, pbuttonslot->getSlotMode())); pbuttonslot->deleteLater(); } } JoyAxisContextMenuHelper &JoyAxisContextMenu::getHelperLocal() { return helper; } AntiMicroX-antimicrox-b300273/src/joyaxiscontextmenu.h000066400000000000000000000030271471077622000230740ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYAXISCONTEXTMENU_H #define JOYAXISCONTEXTMENU_H #include "uihelpers/joyaxiscontextmenuhelper.h" #include class JoyAxis; class QWidget; class JoyAxisContextMenu : public QMenu { Q_OBJECT public: explicit JoyAxisContextMenu(JoyAxis *axis, QWidget *parent = nullptr); void buildMenu(); void buildAxisMenu(); void buildTriggerMenu(); protected: int getPresetIndex(); int getTriggerPresetIndex(); private slots: void setAxisPreset(QAction *action); void setTriggerPreset(QAction *action); void openMouseSettingsDialog(); private: JoyAxisContextMenuHelper &getHelperLocal(); JoyAxis *axis; JoyAxisContextMenuHelper helper; }; #endif // JOYAXISCONTEXTMENU_H AntiMicroX-antimicrox-b300273/src/joybuttoncontextmenu.cpp000066400000000000000000000130431471077622000237750ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joybuttoncontextmenu.h" #include "common.h" #include "globalvariables.h" #include "inputdevice.h" #include "joybuttontypes/joybutton.h" #include #include #include JoyButtonContextMenu::JoyButtonContextMenu(JoyButton *button, QWidget *parent) : QMenu(parent) { this->button = button; connect(this, &JoyButtonContextMenu::aboutToHide, this, &JoyButtonContextMenu::deleteLater); } void JoyButtonContextMenu::buildMenu() { PadderCommon::inputDaemonMutex.lock(); QAction *action = this->addAction(tr("Toggle")); action->setCheckable(true); action->setChecked(button->getToggleState()); connect(action, &QAction::triggered, this, &JoyButtonContextMenu::switchToggle); action = this->addAction(tr("Turbo")); action->setCheckable(true); action->setChecked(button->isUsingTurbo()); connect(action, &QAction::triggered, this, &JoyButtonContextMenu::switchTurbo); this->addSeparator(); action = this->addAction(tr("Clear")); action->setCheckable(false); connect(action, &QAction::triggered, this, &JoyButtonContextMenu::clearButton); this->addSeparator(); QMenu *setSectionMenu = this->addMenu(tr("Set Select")); action = setSectionMenu->addAction(tr("Disabled")); if (button->getChangeSetCondition() == JoyButton::SetChangeDisabled) { action->setCheckable(true); action->setChecked(true); } connect(action, &QAction::triggered, this, &JoyButtonContextMenu::disableSetMode); setSectionMenu->addSeparator(); for (int i = 0; i < GlobalVariables::InputDevice::NUMBER_JOYSETS; i++) { QMenu *tempSetMenu = setSectionMenu->addMenu(tr("Set %1").arg(i + 1)); int setSelection = i * 3; if (i == button->getSetSelection()) { QFont tempFont = tempSetMenu->menuAction()->font(); tempFont.setBold(true); tempSetMenu->menuAction()->setFont(tempFont); } QActionGroup *tempGroup = new QActionGroup(tempSetMenu); createActionForGroup(tempGroup, tr("Set %1 1W"), action, tempSetMenu, setSelection, i, 0, 1); createActionForGroup(tempGroup, tr("Set %1 2W"), action, tempSetMenu, setSelection, i, 1, 2); createActionForGroup(tempGroup, tr("Set %1 WH"), action, tempSetMenu, setSelection, i, 2, 3); if (i == button->getParentSet()->getIndex()) tempSetMenu->setEnabled(false); } PadderCommon::inputDaemonMutex.unlock(); } void JoyButtonContextMenu::createActionForGroup(QActionGroup *tempGroup, QString actionText, QAction *action, QMenu *tempSetMenu, int setSelection, int currentSelection, int setDataInc, int setCondition) { action = tempSetMenu->addAction(actionText.arg(currentSelection + 1)); action->setData(QVariant(setSelection + setDataInc)); action->setCheckable(true); if ((button->getSetSelection() == currentSelection) && (button->getChangeSetCondition() == static_cast(setCondition))) { action->setChecked(true); } connect(action, &QAction::triggered, this, [this, action]() { switchSetMode(action); }); tempGroup->addAction(action); } void JoyButtonContextMenu::switchToggle() { PadderCommon::inputDaemonMutex.lock(); button->setToggle(!button->getToggleState()); PadderCommon::inputDaemonMutex.unlock(); } void JoyButtonContextMenu::switchTurbo() { PadderCommon::inputDaemonMutex.lock(); button->setUseTurbo(!button->isUsingTurbo()); PadderCommon::inputDaemonMutex.unlock(); } void JoyButtonContextMenu::switchSetMode(QAction *action) { int item = action->data().toInt(); int setSelection = item / 3; int setChangeCondition = item % 3; JoyButton::SetChangeCondition temp = JoyButton::SetChangeOneWay; switch (setChangeCondition) { case 0: temp = JoyButton::SetChangeOneWay; break; case 1: temp = JoyButton::SetChangeTwoWay; break; case 2: temp = JoyButton::SetChangeWhileHeld; break; } PadderCommon::inputDaemonMutex.lock(); // First, remove old condition for the button in both sets. // After that, make the new assignment. button->setChangeSetCondition(JoyButton::SetChangeDisabled); button->setChangeSetSelection(setSelection); button->setChangeSetCondition(temp); PadderCommon::inputDaemonMutex.unlock(); } void JoyButtonContextMenu::disableSetMode() { PadderCommon::inputDaemonMutex.lock(); button->setChangeSetCondition(JoyButton::SetChangeDisabled); PadderCommon::inputDaemonMutex.unlock(); } void JoyButtonContextMenu::clearButton() { QMetaObject::invokeMethod(button, "clearSlotsEventReset"); } AntiMicroX-antimicrox-b300273/src/joybuttoncontextmenu.h000066400000000000000000000030531471077622000234420ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYBUTTONCONTEXTMENU_H #define JOYBUTTONCONTEXTMENU_H #include #include class JoyButton; class QWidget; class JoyButtonContextMenu : public QMenu { Q_OBJECT public: explicit JoyButtonContextMenu(JoyButton *button, QWidget *parent = nullptr); void buildMenu(); protected: JoyButton *button; private slots: void switchToggle(); void switchTurbo(); void switchSetMode(QAction *action); void disableSetMode(); void clearButton(); void createActionForGroup(QActionGroup *tempGroup, QString actionText, QAction *action, QMenu *tempSetMenu, int setSelection, int currentSelection, int setDataInc, int setCondition); }; #endif // JOYBUTTONCONTEXTMENU_H AntiMicroX-antimicrox-b300273/src/joybuttonmousehelper.cpp000066400000000000000000000107701471077622000237600ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joybuttonmousehelper.h" #include "globalvariables.h" #include "joybuttontypes/joybutton.h" #include #include #include JoyButtonMouseHelper::JoyButtonMouseHelper(QObject *parent) : QObject(parent) { firstSpringEvent = false; } /** * @brief Perform mouse movement in cursor mode. */ void JoyButtonMouseHelper::moveMouseCursor() { int finalx = 0; int finaly = 0; int elapsedTime = 5; JoyButton::moveMouseCursor(finalx, finaly, elapsedTime, &GlobalVariables::JoyButton::mouseHistoryX, &GlobalVariables::JoyButton::mouseHistoryY, JoyButton::getTestOldMouseTime(), JoyButton::getStaticMouseEventTimer(), GlobalVariables::JoyButton::mouseRefreshRate, GlobalVariables::JoyButton::mouseHistorySize, JoyButton::getCursorXSpeeds(), JoyButton::getCursorYSpeeds(), GlobalVariables::JoyButton::cursorRemainderX, GlobalVariables::JoyButton::cursorRemainderY, GlobalVariables::JoyButton::weightModifier, GlobalVariables::JoyButton::IDLEMOUSEREFRESHRATE, JoyButton::getPendingMouseButtons()); if ((finalx != 0) || (finaly != 0)) emit mouseCursorMoved(finalx, finaly, elapsedTime); } /** * @brief Perform mouse movement in spring mode. */ void JoyButtonMouseHelper::moveSpringMouse() { int finalx = 0; int finaly = 0; bool hasMoved = false; JoyButton::moveSpringMouse(finalx, finaly, hasMoved, GlobalVariables::JoyButton::springModeScreen, JoyButton::getSpringXSpeeds(), JoyButton::getSpringYSpeeds(), JoyButton::getPendingMouseButtons(), GlobalVariables::JoyButton::mouseRefreshRate, GlobalVariables::JoyButton::IDLEMOUSEREFRESHRATE, JoyButton::getStaticMouseEventTimer()); if (hasMoved) emit mouseSpringMoved(finalx, finaly); } /** * @brief Perform mouse events for all buttons and slots. */ void JoyButtonMouseHelper::mouseEvent() { if (!JoyButton::hasCursorEvents(JoyButton::getCursorXSpeeds(), JoyButton::getCursorYSpeeds()) && !JoyButton::hasSpringEvents(JoyButton::getSpringXSpeeds(), JoyButton::getSpringYSpeeds())) { QList *buttonList = JoyButton::getPendingMouseButtons(); QListIterator iter(*buttonList); while (iter.hasNext()) { JoyButton *temp = iter.next(); temp->mouseEvent(); } } moveMouseCursor(); if (JoyButton::hasSpringEvents(JoyButton::getSpringXSpeeds(), JoyButton::getSpringYSpeeds())) { moveSpringMouse(); } JoyButton::restartLastMouseTime(JoyButton::getTestOldMouseTime()); firstSpringEvent = false; } void JoyButtonMouseHelper::resetButtonMouseDistances() { QList *buttonList = JoyButton::getPendingMouseButtons(); for (JoyButton *temp : *buttonList) { temp->resetAccelerationDistances(); } } void JoyButtonMouseHelper::setFirstSpringStatus(bool status) { firstSpringEvent = status; } bool JoyButtonMouseHelper::getFirstSpringStatus() { return firstSpringEvent; } void JoyButtonMouseHelper::carryGamePollRateUpdate(int pollRate) { emit gamepadRefreshRateUpdated(pollRate); } void JoyButtonMouseHelper::carryMouseRefreshRateUpdate(int refreshRate) { emit mouseRefreshRateUpdated(refreshRate); } void JoyButtonMouseHelper::changeThread(QThread *thread) { JoyButton::setStaticMouseThread(thread, JoyButton::getStaticMouseEventTimer(), JoyButton::getTestOldMouseTime(), GlobalVariables::JoyButton::IDLEMOUSEREFRESHRATE, JoyButton::getMouseHelper()); } AntiMicroX-antimicrox-b300273/src/joybuttonmousehelper.h000066400000000000000000000032551471077622000234250ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYBUTTONMOUSEHELPER_H #define JOYBUTTONMOUSEHELPER_H #include class QThread; class JoyButtonMouseHelper : public QObject { Q_OBJECT public: explicit JoyButtonMouseHelper(QObject *parent = nullptr); void resetButtonMouseDistances(); void setFirstSpringStatus(bool status); bool getFirstSpringStatus(); void carryGamePollRateUpdate(int pollRate); void carryMouseRefreshRateUpdate(int refreshRate); signals: void mouseCursorMoved(int mouseX, int mouseY, int elapsed); void mouseSpringMoved(int mouseX, int mouseY); void gamepadRefreshRateUpdated(int pollRate); void mouseRefreshRateUpdated(int refreshRate); public slots: void moveMouseCursor(); void moveSpringMouse(); void mouseEvent(); void changeThread(QThread *thread); private: bool firstSpringEvent; }; #endif // JOYBUTTONMOUSEHELPER_H AntiMicroX-antimicrox-b300273/src/joybuttonslot.cpp000066400000000000000000000321721471077622000224110ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joybuttonslot.h" #include "antkeymapper.h" #include "event.h" #include "globalvariables.h" #include "inputdevice.h" #include #include JoyButtonSlot::JoyButtonSlot(QObject *parent) : QObject(parent) , extraData() { deviceCode = 0; qkeyaliasCode = 0; m_mode = JoyKeyboard; m_distance = 0.0; previousDistance = 0.0; easingActive = false; mix_slots = nullptr; } JoyButtonSlot::JoyButtonSlot(int code, JoySlotInputAction mode, QObject *parent) : JoyButtonSlot(code, 0, mode, parent) { } JoyButtonSlot::JoyButtonSlot(int code, int alias, JoySlotInputAction mode, QObject *parent) : JoyButtonSlot(parent) { if (code > 0) deviceCode = code; if (alias > 0) qkeyaliasCode = alias; m_mode = mode; } JoyButtonSlot::JoyButtonSlot(JoyButtonSlot *slot, QObject *parent) : QObject(parent) , mix_slots(nullptr) , extraData() { copyAssignments(*slot); } JoyButtonSlot::JoyButtonSlot(QString text, JoySlotInputAction mode, QObject *parent) : QObject(parent) , extraData() { deviceCode = 0; qkeyaliasCode = 0; m_mode = mode; m_distance = 0.0; easingActive = false; mix_slots = nullptr; if ((mode == JoyLoadProfile) || (mode == JoyTextEntry) || (mode == JoyExecute)) { m_textData = text; } } JoyButtonSlot::~JoyButtonSlot() {} void JoyButtonSlot::setSlotCode(int code) { if (code >= 0) { deviceCode = code; qkeyaliasCode = 0; } } void JoyButtonSlot::setSlotCode(int code, int alias) { if ((m_mode == JoyButtonSlot::JoyKeyboard) && (code > 0)) { deviceCode = code; qkeyaliasCode = alias; } else if (code >= 0) { deviceCode = code; qkeyaliasCode = 0; } } int JoyButtonSlot::getSlotCodeAlias() const { return qkeyaliasCode; } int JoyButtonSlot::getSlotCode() const { return deviceCode; } void JoyButtonSlot::setSlotMode(JoySlotInputAction selectedMode) { m_mode = selectedMode; } JoyButtonSlot::JoySlotInputAction JoyButtonSlot::getSlotMode() const { return m_mode; } QString JoyButtonSlot::movementString() { QString newlabel = QString(); if (m_mode == JoyMouseMovement) { newlabel.append(tr("Mouse")).append(" "); switch (deviceCode) { case 1: newlabel.append(tr("Up")); break; case 2: newlabel.append(tr("Down")); break; case 3: newlabel.append(tr("Left")); break; case 4: newlabel.append(tr("Right")); break; } } return newlabel; } void JoyButtonSlot::setDistance(double distance) { m_distance = distance; } double JoyButtonSlot::getMouseDistance() { return m_distance; } QElapsedTimer *JoyButtonSlot::getMouseInterval() { return &mouseInterval; } void JoyButtonSlot::restartMouseInterval() { mouseInterval.restart(); } QString JoyButtonSlot::getXmlName() { return GlobalVariables::JoyButtonSlot::xmlName; } QString JoyButtonSlot::getSlotString() { QString newlabel = QString(); qDebug() << "deviceCode in getSlotString() is: " << deviceCode << " for mode: " << m_mode; if (deviceCode >= 0 || m_mode == JoyButtonSlot::JoyMix) { switch (m_mode) { case JoyButtonSlot::JoyKeyboard: { int tempDeviceCode = deviceCode; newlabel = newlabel.append(keysymToKeyString(tempDeviceCode, qkeyaliasCode).toUpper()); break; } case JoyButtonSlot::JoyMouseButton: { newlabel.append(tr("Mouse")).append(" "); switch (deviceCode) { case 1: newlabel.append(tr("LB")); break; case 2: newlabel.append(tr("MB")); break; case 3: newlabel.append(tr("RB")); break; default: newlabel.append(QString::number(deviceCode)); break; } break; } case JoyMouseMovement: { newlabel.append(movementString()); break; } case JoyPause: { int minutes = deviceCode / 1000 / 60; int seconds = (deviceCode / 1000 % 60); int hundredths = deviceCode % 1000 / 10; newlabel.append(tr("Pause")).append(" "); if (minutes > 0) newlabel.append(QString("%1:").arg(minutes, 2, 10, QChar('0'))); newlabel.append(QString("%1.%2").arg(seconds, 2, 10, QChar('0')).arg(hundredths, 2, 10, QChar('0'))); break; } case JoyHold: { int minutes = deviceCode / 1000 / 60; int seconds = (deviceCode / 1000 % 60); int hundredths = deviceCode % 1000 / 10; newlabel.append(tr("Hold")).append(" "); if (minutes > 0) newlabel.append(QString("%1:").arg(minutes, 2, 10, QChar('0'))); newlabel.append(QString("%1.%2").arg(seconds, 2, 10, QChar('0')).arg(hundredths, 2, 10, QChar('0'))); break; } case JoyButtonSlot::JoyCycle: { newlabel.append(tr("Cycle")); break; } case JoyDistance: { QString temp(tr("Distance")); temp.append(" ").append(QString::number(deviceCode).append("%")); newlabel.append(temp); break; } case JoyRelease: { int minutes = deviceCode / 1000 / 60; int seconds = (deviceCode / 1000 % 60); int hundredths = deviceCode % 1000 / 10; newlabel.append(tr("Release")).append(" "); if (minutes > 0) newlabel.append(QString("%1:").arg(minutes, 2, 10, QChar('0'))); newlabel.append(QString("%1.%2").arg(seconds, 2, 10, QChar('0')).arg(hundredths, 2, 10, QChar('0'))); break; } case JoyMouseSpeedMod: { QString temp = QString(); temp.append(tr("Mouse Mod")).append(" "); temp.append(QString::number(deviceCode).append("%")); newlabel.append(temp); break; } case JoyKeyPress: { int minutes = deviceCode / 1000 / 60; int seconds = (deviceCode / 1000 % 60); int hundredths = deviceCode % 1000 / 10; QString temp(tr("Press Time").append(" ")); if (minutes > 0) temp.append(QString("%1:").arg(minutes, 2, 10, QChar('0'))); temp.append(QString("%1.%2").arg(seconds, 2, 10, QChar('0')).arg(hundredths, 2, 10, QChar('0'))); newlabel.append(temp); break; } case JoyDelay: { int minutes = deviceCode / 1000 / 60; int seconds = (deviceCode / 1000 % 60); int hundredths = deviceCode % 1000 / 10; QString temp(tr("Delay").append(" ")); if (minutes > 0) temp.append(QString("%1:").arg(minutes, 2, 10, QChar('0'))); temp.append(QString("%1.%2").arg(seconds, 2, 10, QChar('0')).arg(hundredths, 2, 10, QChar('0'))); newlabel.append(temp); break; } case JoyLoadProfile: { if (!m_textData.isEmpty()) { QFileInfo profileInfo(m_textData); QString temp(tr("Load %1").arg(PadderCommon::getProfileName(profileInfo))); newlabel.append(temp); } break; } case JoySetChange: { newlabel.append(tr("Set Change %1").arg(deviceCode + 1)); break; } case JoyTextEntry: { QString temp = m_textData; if (temp.length() > GlobalVariables::JoyButtonSlot::MAXTEXTENTRYDISPLAYLENGTH) { temp.truncate(GlobalVariables::JoyButtonSlot::MAXTEXTENTRYDISPLAYLENGTH - 3); temp.append("..."); } newlabel.append(tr("[Text] %1").arg(temp)); break; } case JoyExecute: { QString temp = QString(); if (!m_textData.isEmpty()) { QFileInfo tempFileInfo(m_textData); temp.append(tempFileInfo.fileName()); } newlabel.append(tr("[Exec] %1").arg(temp)); break; } case JoyButtonSlot::JoyMix: { bool firstTime = true; for (auto minislot : *getMixSlots()) { if (!firstTime) newlabel.append("+"); firstTime = false; newlabel = newlabel.append(keysymToKeyString(minislot->getSlotCode(), minislot->getSlotCodeAlias()).toUpper()); } break; } } } else { newlabel = newlabel.append(tr("[NO KEY]")); } if (newlabel == tr("[NO KEY]")) { qDebug() << "EMPTY JOYBUTTONSLOT"; } return newlabel; } void JoyButtonSlot::setPreviousDistance(double distance) { previousDistance = distance; } double JoyButtonSlot::getPreviousDistance() const { return previousDistance; } double JoyButtonSlot::getDistance() const { return m_distance; } bool JoyButtonSlot::isModifierKey() { bool modifier = false; if ((m_mode == JoyKeyboard) && AntKeyMapper::getInstance()->isModifierKey(qkeyaliasCode)) { modifier = true; } return modifier; } bool JoyButtonSlot::isEasingActive() const { return easingActive; } void JoyButtonSlot::setEasingStatus(bool isActive) { easingActive = isActive; } QElapsedTimer *JoyButtonSlot::getEasingTime() { return &easingTime; } void JoyButtonSlot::setTextData(QString textData) { m_textData = textData; } QString JoyButtonSlot::getTextData() const { if (m_textData.isNull() || m_textData.isEmpty()) return ""; return m_textData; } void JoyButtonSlot::setExtraData(QVariant data) { this->extraData = data; } QVariant JoyButtonSlot::getExtraData() const { return extraData; } /** * @brief Deep-copies member variables from another JoyButtonSlot object * into this object. * @param[in] slot Slot from which data gets copied */ void JoyButtonSlot::copyAssignments(const JoyButtonSlot &slot) { deviceCode = slot.deviceCode; qkeyaliasCode = slot.qkeyaliasCode; m_mode = slot.m_mode; if (slot.mix_slots != nullptr) { mix_slots = new QList(); for (const auto minislot : *slot.mix_slots) mix_slots->append( new JoyButtonSlot(minislot->getSlotCode(), minislot->getSlotCodeAlias(), minislot->getSlotMode())); } m_distance = slot.m_distance; previousDistance = slot.previousDistance; easingTime = QElapsedTimer(); if (slot.easingTime.isValid()) easingTime.start(); easingActive = slot.easingActive; if (!slot.getTextData().isNull() && (slot.getTextData() != "")) m_textData = slot.getTextData(); extraData = slot.extraData; } void JoyButtonSlot::secureMixSlotsInit() { if (mix_slots == nullptr) { mix_slots = new QList(); // connect(qApp, &QApplication::aboutToQuit, this, &JoyButtonSlot::cleanMixSlots); } } QList *JoyButtonSlot::getMixSlots() { secureMixSlotsInit(); return mix_slots; } void JoyButtonSlot::assignMixSlotsToNull() { mix_slots = nullptr; } void JoyButtonSlot::cleanMixSlots() { if (mix_slots != nullptr) { // disconnect(qApp, &QApplication::aboutToQuit, this, &JoyButtonSlot::cleanMixSlots); if (mix_slots->size() != 0) { qDeleteAll(*mix_slots); mix_slots->clear(); } delete mix_slots; mix_slots = nullptr; } } void JoyButtonSlot::setMixSlots(QList *mixSlots) { mix_slots = mixSlots; } bool JoyButtonSlot::isValidSlot() { bool result = true; switch (m_mode) { case JoyLoadProfile: case JoyTextEntry: case JoyExecute: { if (m_textData.isEmpty()) result = false; break; } case JoySetChange: { if (deviceCode < 0) result = false; break; } case JoyMix: { if (mix_slots->count() == 0) return false; break; } default: { break; } } return result; } JoyButtonSlot &JoyButtonSlot::operator=(JoyButtonSlot *slot) { copyAssignments(*slot); return *this; } AntiMicroX-antimicrox-b300273/src/joybuttonslot.h000066400000000000000000000102761471077622000220570ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYBUTTONSLOT_H #define JOYBUTTONSLOT_H #include #include #include #include #include #include class QXmlStreamReader; class QXmlStreamWriter; /** * @brief Represents action which can be performed after pressing button * * It can represent pressing buttons, moving mouse, running executables, waiting, changing sets etc. */ class JoyButtonSlot : public QObject { Q_OBJECT public: enum JoySlotInputAction { JoyKeyboard = 0, JoyMouseButton, JoyMouseMovement, JoyPause, JoyHold, JoyCycle, JoyDistance, JoyRelease, JoyMouseSpeedMod, JoyKeyPress, JoyDelay, JoyLoadProfile, JoySetChange, JoyTextEntry, JoyExecute, JoyMix }; enum JoySlotMouseDirection { MouseUp = 1, MouseDown, MouseLeft, MouseRight }; enum JoySlotMouseWheelButton { MouseWheelUp = 4, MouseWheelDown = 5, MouseWheelLeft = 6, MouseWheelRight = 7 }; enum JoySlotMouseButton { MouseLB = 1, MouseMB, MouseRB }; explicit JoyButtonSlot(QObject *parent = nullptr); explicit JoyButtonSlot(int code, JoySlotInputAction mode, QObject *parent = nullptr); explicit JoyButtonSlot(int code, int alias, JoySlotInputAction mode, QObject *parent = nullptr); explicit JoyButtonSlot(JoyButtonSlot *slot, QObject *parent = nullptr); explicit JoyButtonSlot(QString text, JoySlotInputAction mode, QObject *parent = nullptr); ~JoyButtonSlot(); void setSlotCode(int code); int getSlotCode() const; void setSlotMode(JoySlotInputAction selectedMode); JoySlotInputAction getSlotMode() const; QString movementString(); void setMouseSpeed(int value); void setDistance(double distance); double getMouseDistance(); QElapsedTimer *getMouseInterval(); void restartMouseInterval(); QString getXmlName(); QString getSlotString(); void setSlotCode(int code, int alias); int getSlotCodeAlias() const; void setPreviousDistance(double distance); double getPreviousDistance() const; double getDistance() const; bool isModifierKey(); bool isEasingActive() const; void setEasingStatus(bool isActive); QElapsedTimer *getEasingTime(); void setTextData(QString textData); QString getTextData() const; void setExtraData(QVariant data); QVariant getExtraData() const; void setMixSlots(QList *slots); QList *getMixSlots(); template void appendMiniSlot(T minislot) { secureMixSlotsInit(); mix_slots->append(minislot); } void assignMixSlotsToNull(); bool isValidSlot(); void cleanMixSlots(); JoyButtonSlot &operator=(JoyButtonSlot *slot); private: void copyAssignments(const JoyButtonSlot &rhs); void secureMixSlotsInit(); int deviceCode; int qkeyaliasCode; JoySlotInputAction m_mode; QList *mix_slots; double m_distance; double previousDistance; QElapsedTimer mouseInterval; QElapsedTimer easingTime; bool easingActive; QString m_textData; QVariant extraData; }; Q_DECLARE_METATYPE(JoyButtonSlot *) Q_DECLARE_METATYPE(JoyButtonSlot::JoySlotInputAction) #endif // JOYBUTTONSLOT_H AntiMicroX-antimicrox-b300273/src/joybuttonstatusbox.cpp000066400000000000000000000032721471077622000234630ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joybuttonstatusbox.h" #include "joybuttontypes/joybutton.h" #include #include #include JoyButtonStatusBox::JoyButtonStatusBox(JoyButton *button, QWidget *parent) : QPushButton(parent) { this->button = button; isflashing = false; setText(QString::number(button->getRealJoyNumber())); connect(button, &JoyButton::clicked, this, &JoyButtonStatusBox::flash); connect(button, &JoyButton::released, this, &JoyButtonStatusBox::unflash); } JoyButton *JoyButtonStatusBox::getJoyButton() const { return button; } bool JoyButtonStatusBox::isButtonFlashing() { return isflashing; } void JoyButtonStatusBox::flash() { isflashing = true; this->style()->unpolish(this); this->style()->polish(this); } void JoyButtonStatusBox::unflash() { isflashing = false; this->style()->unpolish(this); this->style()->polish(this); } AntiMicroX-antimicrox-b300273/src/joybuttonstatusbox.h000066400000000000000000000025121471077622000231240ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYBUTTONSTATUSBOX_H #define JOYBUTTONSTATUSBOX_H #include class JoyButton; class QWidget; class JoyButtonStatusBox : public QPushButton { Q_OBJECT Q_PROPERTY(bool isflashing READ isButtonFlashing) public: explicit JoyButtonStatusBox(JoyButton *button, QWidget *parent = nullptr); JoyButton *getJoyButton() const; bool isButtonFlashing(); private slots: void flash(); void unflash(); private: JoyButton *button; bool isflashing; }; #endif // JOYBUTTONSTATUSBOX_H AntiMicroX-antimicrox-b300273/src/joybuttontypes/000077500000000000000000000000001471077622000220635ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/joybuttontypes/joyaccelerometerbutton.cpp000066400000000000000000000035471471077622000273700ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joyaccelerometerbutton.h" #include "joysensordirection.h" JoyAccelerometerButton::JoyAccelerometerButton(JoySensor *sensor, int sdl_button_index, int originset, SetJoystick *parentSet, QObject *parent) : JoySensorButton(sensor, sdl_button_index, originset, parentSet, parent) { } /** * @brief Get translated accelerometer direction name of this button * @returns Translated direction name */ QString JoyAccelerometerButton::getDirectionName() const { QString label = QString(); switch (m_index_sdl) { case JoySensorDirection::SENSOR_UP: label.append(tr("Up")); break; case JoySensorDirection::SENSOR_DOWN: label.append(tr("Down")); break; case JoySensorDirection::SENSOR_LEFT: label.append(tr("Left")); break; case JoySensorDirection::SENSOR_RIGHT: label.append(tr("Right")); break; case JoySensorDirection::SENSOR_BWD: label.append(tr("Shock")); break; default: WARN() << "unknown accelerometer direction"; break; } return label; } AntiMicroX-antimicrox-b300273/src/joybuttontypes/joyaccelerometerbutton.h000066400000000000000000000022431471077622000270250ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "joybuttontypes/joysensorbutton.h" /** * @brief Represents an accelerometer mapping in a SetJoystick */ class JoyAccelerometerButton : public JoySensorButton { Q_OBJECT public: explicit JoyAccelerometerButton(JoySensor *sensor, int sdl_button_index, int originset, SetJoystick *parentSet, QObject *parent); virtual QString getDirectionName() const override; }; AntiMicroX-antimicrox-b300273/src/joybuttontypes/joyaxisbutton.cpp000066400000000000000000000121771471077622000255210ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joyaxisbutton.h" #include "event.h" #include "globalvariables.h" #include "joyaxis.h" #include "joybutton.h" #include "setjoystick.h" #include "vdpad.h" #include #include JoyAxisButton::JoyAxisButton(JoyAxis *axis, int index, int originset, SetJoystick *parentSet, QObject *parent) : JoyGradientButton(index, originset, parentSet, parent) { m_axis = axis; } QString JoyAxisButton::getPartialName(bool forceFullFormat, bool displayNames) const { QString temp = QString(m_axis->getPartialName(forceFullFormat, displayNames)); temp.append(": "); if (!buttonName.isEmpty() && displayNames) { if (forceFullFormat) { temp.append(tr("Button")).append(" "); } temp.append(buttonName); } else if (!defaultButtonName.isEmpty() && displayNames) { if (forceFullFormat) { temp.append(tr("Button")).append(" "); } temp.append(defaultButtonName); } else { QString buttontype = QString(); switch (m_index_sdl) { case 0: buttontype = tr("Negative"); break; case 1: buttontype = tr("Positive"); break; default: buttontype = tr("Unknown"); break; } temp.append(tr("Button")).append(" ").append(buttontype); } return temp; } QString JoyAxisButton::getXmlName() { return GlobalVariables::JoyAxisButton::xmlName; } void JoyAxisButton::setChangeSetCondition(SetChangeCondition condition, bool passive, bool updateActiveString) { SetChangeCondition oldCondition = setSelectionCondition; if ((condition != setSelectionCondition) && !passive) { if ((condition == SetChangeWhileHeld) || (condition == SetChangeTwoWay)) { // Set new condition emit setAssignmentChanged(m_index_sdl, m_axis->getIndex(), setSelection, condition); } else if ((setSelectionCondition == SetChangeWhileHeld) || (setSelectionCondition == SetChangeTwoWay)) { // Remove old condition emit setAssignmentChanged(m_index_sdl, m_axis->getIndex(), setSelection, SetChangeDisabled); } setSelectionCondition = condition; } else if (passive) { setSelectionCondition = condition; } if (setSelectionCondition == SetChangeDisabled) { setChangeSetSelection(-1); } if (setSelectionCondition != oldCondition) { if (updateActiveString) { buildActiveZoneSummaryString(); } emit propertyUpdated(); } } /** * @brief Get the distance that an element is away from its assigned * dead zone * @return Normalized distance away from dead zone */ double JoyAxisButton::getDistanceFromDeadZone() { return m_axis->getDistanceFromDeadZone(); } /** * @brief Get the distance factor that should be used for mouse movement * @return Distance factor that should be used for mouse movement */ double JoyAxisButton::getMouseDistanceFromDeadZone() { return this->getDistanceFromDeadZone(); } void JoyAxisButton::setVDPad(VDPad *vdpad) { if (m_axis->isPartControlStick()) { m_axis->removeControlStick(); } JoyButton::setVDPad(vdpad); } /** * @brief Set the turbo mode that the button should use * @param Mode that should be used */ void JoyAxisButton::setTurboMode(TurboMode mode) { if (isPartRealAxis()) { currentTurboMode = mode; } } /** * @brief Check if button should be considered a part of a real controller * axis. Needed for some dialogs so the program won't have to resort to * type checking. * @return Status of being part of a real controller axis */ bool JoyAxisButton::isPartRealAxis() { return true; } double JoyAxisButton::getAccelerationDistance() { return m_axis->getRawDistance(m_axis->getCurrentThrottledValue()); } double JoyAxisButton::getLastAccelerationDistance() { return m_axis->getRawDistance(m_axis->getLastKnownThrottleValue()); } double JoyAxisButton::getLastMouseDistanceFromDeadZone() { double distance = 0.0; if (m_axis->getAxisButtonByValue(m_axis->getLastKnownThrottleValue()) == this) { distance = m_axis->getDistanceFromDeadZone(m_axis->getLastKnownThrottleValue()); } return distance; } JoyAxis *JoyAxisButton::getAxis() const { return m_axis; } AntiMicroX-antimicrox-b300273/src/joybuttontypes/joyaxisbutton.h000066400000000000000000000037221471077622000251620ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYAXISBUTTON_H #define JOYAXISBUTTON_H #include "joybuttontypes/joygradientbutton.h" #include "logger.h" class VDPad; class SetJoystick; class JoyAxis; class JoyAxisButton : public JoyGradientButton { Q_OBJECT public: explicit JoyAxisButton(JoyAxis *axis, int index, int originset, SetJoystick *parentSet, QObject *parent); virtual QString getPartialName(bool forceFullFormat = false, bool displayNames = false) const; virtual QString getXmlName(); virtual double getDistanceFromDeadZone(); virtual double getMouseDistanceFromDeadZone(); virtual double getLastMouseDistanceFromDeadZone(); virtual void setChangeSetCondition(SetChangeCondition condition, bool passive = false, bool updateActiveString = true); virtual void setVDPad(VDPad *vdpad); virtual void setTurboMode(TurboMode mode); virtual bool isPartRealAxis(); virtual double getAccelerationDistance(); virtual double getLastAccelerationDistance(); JoyAxis *getAxis() const; signals: void setAssignmentChanged(int current_button, int axis_index, int associated_set, int mode); private: JoyAxis *m_axis; }; #endif // JOYAXISBUTTON_H AntiMicroX-antimicrox-b300273/src/joybuttontypes/joybutton.cpp000066400000000000000000004447601471077622000246430ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joybutton.h" #include "event.h" #include "inputdevice.h" #include "logger.h" #include "setjoystick.h" #include "vdpad.h" #include "SDL2/SDL_events.h" #include "eventhandlerfactory.h" #include //#include #include #include #include #include #include #include const JoyButton::JoyMouseCurve JoyButton::DEFAULTMOUSECURVE = JoyButton::EnhancedPrecisionCurve; const JoyButton::SetChangeCondition JoyButton::DEFAULTSETCONDITION = JoyButton::SetChangeDisabled; const JoyButton::JoyMouseMovementMode JoyButton::DEFAULTMOUSEMODE = JoyButton::MouseCursor; const JoyButton::TurboMode JoyButton::DEFAULTTURBOMODE = JoyButton::NormalTurbo; const JoyButton::JoyExtraAccelerationCurve JoyButton::DEFAULTEXTRAACCELCURVE = JoyButton::LinearAccelCurve; JoyButtonSlot *JoyButton::lastActiveKey = nullptr; // Keep track of active Mouse Speed Mod slots. QList JoyButton::mouseSpeedModList; // Lists used for cursor mode calculations. QList JoyButton::cursorXSpeeds; QList JoyButton::cursorYSpeeds; // Lists used for spring mode calculations. QList JoyButton::springXSpeeds; QList JoyButton::springYSpeeds; // Temporary test object to test old mouse time behavior. QElapsedTimer JoyButton::testOldMouseTime; // time when minislots next to each other in thread pool are waiting to execute function // at the same time int JoyButton::timeBetweenMiniSlots = 55; int JoyButton::allSlotTimeBetweenSlots = 0; // Helper object to have a single mouse event for all JoyButton // instances. JoyButtonMouseHelper JoyButton::mouseHelper; QTimer JoyButton::staticMouseEventTimer; QList JoyButton::pendingMouseButtons; // IT CAN BE HERE // LOOK FOR JoyCycle and put JoyMix next to the slots types JoyButton::JoyButton(int sdl_button_index, int originset, SetJoystick *parentSet, QObject *parent) : QObject(parent) { m_vdpad = nullptr; slotiter = nullptr; threadPool = QThreadPool::globalInstance(); turboTimer.setParent(this); pauseTimer.setParent(this); holdTimer.setParent(this); pauseWaitTimer.setParent(this); createDeskTimer.setParent(this); releaseDeskTimer.setParent(this); mouseWheelVerticalEventTimer.setParent(this); mouseWheelHorizontalEventTimer.setParent(this); setChangeTimer.setParent(this); keyPressTimer.setParent(this); delayTimer.setParent(this); slotSetChangeTimer.setParent(this); setChangeTimer.setSingleShot(true); slotSetChangeTimer.setSingleShot(true); m_parentSet = parentSet; connect(&pauseWaitTimer, &QTimer::timeout, this, &JoyButton::pauseWaitEvent); connect(&keyPressTimer, &QTimer::timeout, this, &JoyButton::keyPressEvent); connect(&holdTimer, &QTimer::timeout, this, &JoyButton::holdEvent); connect(&delayTimer, &QTimer::timeout, this, &JoyButton::delayEvent); connect(&createDeskTimer, &QTimer::timeout, this, &JoyButton::waitForDeskEvent); connect(&releaseDeskTimer, &QTimer::timeout, this, &JoyButton::waitForReleaseDeskEvent); connect(&turboTimer, &QTimer::timeout, this, &JoyButton::turboEvent); connect(&mouseWheelVerticalEventTimer, &QTimer::timeout, this, &JoyButton::wheelEventVertical); connect(&mouseWheelHorizontalEventTimer, &QTimer::timeout, this, &JoyButton::wheelEventHorizontal); connect(&setChangeTimer, &QTimer::timeout, this, &JoyButton::checkForSetChange); connect(&slotSetChangeTimer, &QTimer::timeout, this, &JoyButton::slotSetChange); // Will only matter on the first call establishMouseTimerConnections(); // Make sure to call before calling reset resetAllProperties(); m_index_sdl = sdl_button_index; m_originset = originset; quitEvent = true; DEBUG() << "Created button with ID: " << m_index_sdl << " For set: " << originset << " Name: " << getName(); } JoyButton::~JoyButton() { // threadPool->clear(); reset(); // resetPrivVars(); } void JoyButton::queuePendingEvent(bool pressed, bool ignoresets) { updatePendingParams(false, false, false); if (m_vdpad != nullptr) vdpadPassEvent(pressed, ignoresets); else updatePendingParams(true, pressed, ignoresets); } void JoyButton::activatePendingEvent() { if (pendingEvent) { joyEvent(pendingPress, pendingIgnoreSets); updatePendingParams(false, false, false); } } bool JoyButton::hasPendingEvent() { return pendingEvent; } void JoyButton::clearPendingEvent() { updatePendingParams(false, false, false); } void JoyButton::vdpadPassEvent(bool pressed, bool ignoresets) { if ((m_vdpad != nullptr) && (pressed != isButtonPressed)) { isButtonPressed = pressed; if (isButtonPressed) emit clicked(m_index_sdl); else emit released(m_index_sdl); if (!ignoresets) m_vdpad->queueJoyEvent(ignoresets); else m_vdpad->joyEvent(pressed, ignoresets); } } /** * @brief Activates mapped slots and generates QT events * which highlight pressed controller buttons. */ void JoyButton::joyEvent(bool pressed, bool ignoresets) { if (Logger::isDebugEnabled()) DEBUG() << "Processing JoyButton::joyEvent for: " << getName() << " SDL index: " << m_index_sdl << " className: " << metaObject()->className(); if ((m_vdpad != nullptr) && !pendingEvent) { vdpadPassEvent(pressed, ignoresets); } else if (ignoreEvents && (pressed != isButtonPressed)) { isButtonPressed = pressed; if (isButtonPressed) emit clicked(m_index_sdl); else emit released(m_index_sdl); } else { if (pressed != isDown) { if (pressed) { emit clicked(m_index_sdl); if (updateInitAccelValues) oldAccelMulti = updateOldAccelMulti = accelTravel = 0.0; } else { emit released(m_index_sdl); } bool activePress = pressed; setChangeTimer.stop(); if (m_toggle && pressed) { isDown = true; toggleActiveState = !toggleActiveState; if (!isButtonPressed) { m_ignoresets = ignoresets; isButtonPressed = !isButtonPressed; ignoreSetQueue.enqueue(ignoresets); isButtonPressedQueue.enqueue(isButtonPressed); } else { activePress = false; } } else if (m_toggle && !pressed && isDown) { isDown = false; if (!toggleActiveState) { m_ignoresets = ignoresets; isButtonPressed = !isButtonPressed; ignoreSetQueue.enqueue(ignoresets); isButtonPressedQueue.enqueue(isButtonPressed); } } else { m_ignoresets = ignoresets; isButtonPressed = isDown = pressed; ignoreSetQueue.enqueue(ignoresets); isButtonPressedQueue.enqueue(isButtonPressed); } if (m_useTurbo) { if (isButtonPressed && activePress && !turboTimer.isActive()) { startSequenceOfPressActive(true, tr("Processing turbo for #%1 - %2")); turboEvent(); } else if (!isButtonPressed && !activePress && turboTimer.isActive()) { turboTimer.stop(); Q_ASSERT(!m_parentSet.isNull()); qDebug() << tr("Finishing turbo for button #%1 - %2") .arg(m_parentSet->getInputDevice()->getRealJoyNumber()) .arg(getPartialName()); if (isKeyPressed) turboEvent(); else lastDistance = getMouseDistanceFromDeadZone(); } } // Toogle is enabled and a controller button change has occurred. // Switch to a different distance zone if appropriate else if (m_toggle && !activePress && isButtonPressed) { updateParamsAfterDistEvent(); } else if (isButtonPressed && activePress) { startSequenceOfPressActive(false, "Processing press for button #%1 - %2"); if (!keyPressTimer.isActive()) { checkForPressedSetChange(); if (!setChangeTimer.isActive()) waitForDeskEvent(); } } else if (!isButtonPressed && !activePress) { qDebug() << QString("Processing release for button #%1 - %2") .arg(m_parentSet->getInputDevice()->getRealJoyNumber()) .arg(getPartialName()); waitForReleaseDeskEvent(); } if (updateInitAccelValues) updateMouseParams(false, false, 0.0); } else if (!m_useTurbo && isButtonPressed) { resetAccelerationDistances(); currentAccelerationDistance = getAccelerationDistance(); if (!setChangeTimer.isActive()) updateParamsAfterDistEvent(); } } updateInitAccelValues = true; } void JoyButton::updateParamsAfterDistEvent() { if (distanceEvent()) { qDebug() << tr("Distance change for button #%1 - %2") .arg(m_parentSet->getInputDevice()->getRealJoyNumber()) .arg(getPartialName()); quitEvent = true; buttonHold.restart(); buttonHeldRelease.restart(); keyPressHold.restart(); releaseDeskTimer.stop(); if (!keyPressTimer.isActive()) waitForDeskEvent(); } } void JoyButton::startSequenceOfPressActive(bool isTurbo, QString debugText) { if (cycleResetActive && (cycleResetHold.elapsed() >= cycleResetInterval) && (slotiter != nullptr)) { slotiter->toFront(); currentCycle = nullptr; previousCycle = nullptr; } buttonHold.restart(); buttonHeldRelease.restart(); keyPressHold.restart(); cycleResetHold.restart(); if (isTurbo) turboTimer.start(); else releaseDeskTimer.stop(); // Newly activated button. Just entered safe zone. if (updateInitAccelValues) initializeDistanceValues(); currentAccelerationDistance = getAccelerationDistance(); Q_ASSERT(!m_parentSet.isNull()); qDebug() << debugText.arg(m_parentSet->getInputDevice()->getRealJoyNumber()).arg(getPartialName()); } /** * @brief Get 0 indexed number of SDL button index * @return 0 indexed button index number */ int JoyButton::getJoyNumber() { return m_index_sdl; } /** * @brief Get a 1 indexed number of button * @return 1 indexed button index number */ int JoyButton::getRealJoyNumber() const { return m_index_sdl + 1; } void JoyButton::setJoyNumber(int index) { m_index_sdl = index; } void JoyButton::setToggle(bool toggle) { if (toggle != m_toggle) { m_toggle = toggle; emit toggleChanged(toggle); emit propertyUpdated(); } } void JoyButton::setTurboInterval(int interval) { if ((interval < 10) && (interval != this->turboInterval)) { this->setUseTurbo(false); interval = 0; } this->turboInterval = interval; emit turboIntervalChanged(interval); emit propertyUpdated(); } void JoyButton::reset() { resetPrivVars(); } void JoyButton::resetPrivVars() { disconnectPropertyUpdatedConnections(); stopTimers(true); releaseActiveSlots(); clearAssignedSlots(); clearQueues(); resetAllProperties(); // quitEvent changed here } void JoyButton::reset(int index) { JoyButton::reset(); m_index_sdl = index; } bool JoyButton::getToggleState() { return m_toggle; } int JoyButton::getTurboInterval() { return turboInterval; } void JoyButton::turboEvent() { changeTurboParams(isKeyPressed, isButtonPressed); } void JoyButton::changeTurboParams(bool _isKeyPressed, bool isButtonPressed) { if (!isButtonPressedQueue.isEmpty()) { if (!_isKeyPressed) { ignoreSetQueue.clear(); isButtonPressedQueue.clear(); isButtonPressedQueue.enqueue(isButtonPressed); } else { isButtonPressedQueue.enqueue(!isButtonPressed); } ignoreSetQueue.enqueue(false); } if (!_isKeyPressed) createDeskEvent(); else releaseDeskEvent(); isKeyPressed = !_isKeyPressed; if (turboTimer.isActive()) { int tempInterval = turboInterval / 2; if (turboTimer.interval() != tempInterval) turboTimer.start(tempInterval); } } bool JoyButton::distanceEvent() { bool released = false; if (slotiter != nullptr) { QReadLocker tempLocker(&assignmentsLock); if (containsDistanceSlots()) { double currentDistance = getDistanceFromDeadZone(); double tempDistance = 0.0; JoyButtonSlot *previousDistanceSlot = nullptr; QListIterator iter(*getAssignedSlots()); if (previousCycle != nullptr) { qDebug() << "find previous Cycle in next steps in assignments and skip to it"; iter.findNext(previousCycle); } while (iter.hasNext()) { JoyButtonSlot *slot = iter.next(); int tempcode = slot->getSlotCode(); if (slot->getSlotMode() == JoyButtonSlot::JoyDistance) { tempDistance += (tempcode / 100.0); if (currentDistance < tempDistance) iter.toBack(); else previousDistanceSlot = slot; } else if (slot->getSlotMode() == JoyButtonSlot::JoyCycle) { tempDistance = 0.0; iter.toBack(); } } // No applicable distance slot if (!previousDistanceSlot) { if (m_currentDistance != nullptr) { // Distance slot is currently active. // Release slots, return iterator to // the front, and nullify currentDistance pauseWaitTimer.stop(); holdTimer.stop(); // Release stuff releaseActiveSlots(); currentPause = currentHold = nullptr; slotiter->toFront(); if (previousCycle != nullptr) slotiter->findNext(previousCycle); m_currentDistance = nullptr; released = true; } } // An applicable distance slot was found else { if (m_currentDistance != previousDistanceSlot) { // Active distance slot is not the applicable slot. // Deactive slots in previous distance range and // activate new slots. Set currentDistance to // new slot. pauseWaitTimer.stop(); holdTimer.stop(); // Release stuff releaseActiveSlots(); currentPause = currentHold = nullptr; qDebug() << "Deactive slots in previous range and activate new slots"; slotiter->toFront(); if (previousCycle != nullptr) { qDebug() << "Find previous Cycle in slotiter starting from beginning"; slotiter->findNext(previousCycle); } slotiter->findNext(previousDistanceSlot); m_currentDistance = previousDistanceSlot; released = true; } } } } return released; } void JoyButton::createDeskEvent() { quitEvent = false; if (slotiter == nullptr) { assignmentsLock.lockForRead(); slotiter = new QListIterator(*getAssignedSlots()); assignmentsLock.unlock(); distanceEvent(); } else if (!slotiter->hasPrevious()) { distanceEvent(); } else if (currentCycle != nullptr) { currentCycle = nullptr; distanceEvent(); } assignmentsLock.lockForRead(); activateSlots(); assignmentsLock.unlock(); if (currentCycle != nullptr) quitEvent = true; else if ((currentPause == nullptr) && (currentHold == nullptr) && !keyPressTimer.isActive()) quitEvent = true; } void JoyButton::activateSlots() { bool countForAllTime = false; if (allSlotTimeBetweenSlots == 0) countForAllTime = true; if (slotiter != nullptr) { QWriteLocker tempLocker(&activeZoneLock); bool exit = false; bool delaySequence = false; int i = 0; while (slotiter->hasNext() && !exit) { JoyButtonSlot *slot = slotiter->next(); if (slot->getSlotMode() == JoyButtonSlot::JoyMix) { qDebug() << "JOYMIX IN ACTIVATESLOTS"; if (slot->getMixSlots() != nullptr) { QListIterator mini_it(*slot->getMixSlots()); QListIterator *it(&mini_it); int countMinis = slot->getMixSlots()->count(); int timeX = countMinis; std::chrono::time_point t1, t2; t1 = std::chrono::high_resolution_clock::now(); while (it->hasNext()) { JoyButtonSlot *slotmini = it->next(); qDebug() << "Run activated mini slot - name - deviceCode - mode: " << slotmini->getSlotString() << " - " << slotmini->getSlotCode() << " - " << slotmini->getSlotMode(); MiniSlotRun *minijob = new MiniSlotRun(slot, slotmini, this, timeBetweenMiniSlots * timeX); minijob->setAutoDelete(false); threadPool->start(minijob); timeX--; if (timeBetweenMiniSlots == 55) { t2 = std::chrono::high_resolution_clock::now(); timeBetweenMiniSlots = std::chrono::duration_cast(t2 - t1).count(); } } if (countForAllTime) { allSlotTimeBetweenSlots += countMinis * timeBetweenMiniSlots; } threadPool->waitForDone(); i++; if (!slotiter->hasNext()) break; } } else { qDebug() << "Check now simple slots"; addEachSlotToActives(slot, i, delaySequence, exit, slotiter); } } if (delaySequence && !getActiveSlots().isEmpty()) { keyPressHold.restart(); keyPressEvent(); } } } void JoyButton::activateMiniSlots(JoyButtonSlot *slot, JoyButtonSlot *mix) { int tempcode = slot->getSlotCode(); JoyButtonSlot::JoySlotInputAction mode = slot->getSlotMode(); if (mode == JoyButtonSlot::JoyKeyboard) { sendKeybEvent(slot, true); getActiveSlotsLocal().append(slot); int oldvalue = GlobalVariables::JoyButton::JoyButton::activeKeys.value(tempcode, 0) + 1; GlobalVariables::JoyButton::JoyButton::activeKeys.insert(tempcode, oldvalue); if (!slot->isModifierKey()) { qDebug() << "There has been assigned a lastActiveKey " << slot->getSlotString(); lastActiveKey = mix; } else { qDebug() << "It's not modifier key. lastActiveKey is null pointer"; lastActiveKey = nullptr; } } } void JoyButton::addEachSlotToActives(JoyButtonSlot *slot, int &i, bool &delaySequence, bool &exit, QListIterator *slotiter) { int tempcode = slot->getSlotCode(); JoyButtonSlot::JoySlotInputAction mode = slot->getSlotMode(); switch (mode) { case JoyButtonSlot::JoyKeyboard: { i++; qDebug() << i << ": It's a JoyKeyboard with code: " << tempcode << " and name: " << slot->getSlotString(); sendevent(slot, true); getActiveSlotsLocal().append(slot); int oldvalue = GlobalVariables::JoyButton::JoyButton::activeKeys.value(tempcode, 0) + 1; GlobalVariables::JoyButton::JoyButton::activeKeys.insert(tempcode, oldvalue); if (!slot->isModifierKey()) { qDebug() << "There has been assigned a lastActiveKey " << slot->getSlotString(); lastActiveKey = slot; } else { qDebug() << "It's not modifier key. lastActiveKey is null pointer"; lastActiveKey = nullptr; } break; } case JoyButtonSlot::JoyMouseButton: { i++; qDebug() << i << ": It's a JoyMouseButton with code: " << tempcode << " and name: " << slot->getSlotString(); if ((tempcode == static_cast(JoyButtonSlot::MouseWheelUp)) || (tempcode == static_cast(JoyButtonSlot::MouseWheelDown))) { slot->getMouseInterval()->restart(); wheelVerticalTime.restart(); currentWheelVerticalEvent = slot; getActiveSlotsLocal().append(slot); wheelEventVertical(); currentWheelVerticalEvent = nullptr; } else if ((tempcode == static_cast(JoyButtonSlot::MouseWheelLeft)) || (tempcode == static_cast(JoyButtonSlot::MouseWheelRight))) { slot->getMouseInterval()->restart(); wheelHorizontalTime.restart(); currentWheelHorizontalEvent = slot; getActiveSlotsLocal().append(slot); wheelEventHorizontal(); currentWheelHorizontalEvent = nullptr; } else { sendevent(slot, true); getActiveSlotsLocal().append(slot); int oldvalue = GlobalVariables::JoyButton::JoyButton::activeMouseButtons.value(tempcode, 0) + 1; GlobalVariables::JoyButton::JoyButton::activeMouseButtons.insert(tempcode, oldvalue); } break; } case JoyButtonSlot::JoyMouseMovement: { i++; qDebug() << i << ": It's a JoyMouseMovement with code: " << tempcode << " and name: " << slot->getSlotString(); slot->getMouseInterval()->restart(); getActiveSlotsLocal().append(slot); if (pendingMouseButtons.size() == 0) mouseHelper.setFirstSpringStatus(true); pendingMouseButtons.append(this); mouseEventQueue.enqueue(slot); // Temporarily lower timer interval. Helps improve mouse control // precision on the lower end of an axis. if (!staticMouseEventTimer.isActive() || (staticMouseEventTimer.interval() != 0)) { if (!staticMouseEventTimer.isActive() || (staticMouseEventTimer.interval() == GlobalVariables::JoyButton::IDLEMOUSEREFRESHRATE)) { int tempRate = qBound(0, GlobalVariables::JoyButton::mouseRefreshRate - GlobalVariables::JoyButton::gamepadRefreshRate, GlobalVariables::JoyButton::MAXIMUMMOUSEREFRESHRATE); staticMouseEventTimer.start(tempRate); testOldMouseTime.restart(); accelExtraDurationTime.restart(); } } break; } case JoyButtonSlot::JoyPause: { i++; qDebug() << i << ": It's a JoyPause with code: " << tempcode << " and name: " << slot->getSlotString(); if (!getActiveSlots().isEmpty()) { qDebug() << "active slots QHash is not empty"; if (slotiter->hasPrevious()) { i--; slotiter->previous(); } delaySequence = true; exit = true; } // Segment can be ignored on a 0 interval pause else if (tempcode > 0) { qDebug() << "active slots QHash is empty"; currentPause = slot; pauseHold.restart(); inpauseHold.restart(); pauseWaitTimer.start(0); exit = true; } break; } case JoyButtonSlot::JoyHold: { i++; qDebug() << i << ": It's a JoyHold with code: " << tempcode << " and name: " << slot->getSlotString(); currentHold = slot; holdTimer.start(0); exit = true; break; } case JoyButtonSlot::JoyDelay: { i++; qDebug() << i << ": It's a JoyDelay with code: " << tempcode << " and name: " << slot->getSlotString(); currentDelay = slot; buttonDelay.restart(); delayTimer.start(0); exit = true; break; } case JoyButtonSlot::JoyCycle: { i++; qDebug() << i << ": It's a JoyCycle with code: " << tempcode << " and name: " << slot->getSlotString(); currentCycle = slot; exit = true; break; } case JoyButtonSlot::JoyDistance: { i++; qDebug() << i << ": It's a JoyDistance with code: " << tempcode << " and name: " << slot->getSlotString(); exit = true; break; } case JoyButtonSlot::JoyRelease: { i++; qDebug() << i << ": It's a JoyRelease with code: " << tempcode << " and name: " << slot->getSlotString(); if (currentRelease == nullptr) { findJoySlotsEnd(slotiter); } else if ((currentRelease != nullptr) && getActiveSlots().isEmpty()) { qDebug() << "current is release but activeSlots is empty"; exit = true; } else if ((currentRelease != nullptr) && !getActiveSlots().isEmpty()) { qDebug() << "current is release and activeSlots is not empty"; if (slotiter->hasPrevious()) { qDebug() << "Back to previous slotiter from release"; i--; slotiter->previous(); } delaySequence = true; exit = true; } break; } case JoyButtonSlot::JoyMouseSpeedMod: { i++; qDebug() << i << ": It's a JoyMouseSpeedMod with code: " << tempcode << " and name: " << slot->getSlotString(); GlobalVariables::JoyButton::mouseSpeedModifier = tempcode * 0.01; mouseSpeedModList.append(slot); getActiveSlotsLocal().append(slot); break; } case JoyButtonSlot::JoyKeyPress: { i++; qDebug() << i << ": It's a JoyKeyPress with code: " << tempcode << " and name: " << slot->getSlotString(); if (getActiveSlots().isEmpty()) { qDebug() << "activeSlots is empty. It's a true delaySequence and assigned currentKeyPress"; delaySequence = true; currentKeyPress = slot; } else { qDebug() << "activeSlots is not empty. It's a true delaySequence and exit"; if (slotiter->hasPrevious()) { qDebug() << "Back to previous slotiter from JoyKeyPress"; i--; slotiter->previous(); } delaySequence = true; exit = true; } break; } case JoyButtonSlot::JoyLoadProfile: { i++; qDebug() << i << ": It's a JoyLoadProfile with code: " << tempcode << " and name: " << slot->getSlotString(); releaseActiveSlots(); slotiter->toBack(); exit = true; QString location = slot->getTextData(); if (!location.isEmpty()) m_parentSet->getInputDevice()->sendLoadProfileRequest(location); break; } case JoyButtonSlot::JoySetChange: { i++; qDebug() << i << ": It's a JoySetChange with code: " << tempcode << " and name: " << slot->getSlotString(); getActiveSlotsLocal().append(slot); break; } case JoyButtonSlot::JoyTextEntry: case JoyButtonSlot::JoyExecute: { i++; qDebug() << i << ": It's a JoyExecute or JoyTextEntry with code: " << tempcode << " and name: " << slot->getSlotString(); sendevent(slot, true); break; } default: break; } } void JoyButton::slotSetChange() { if (currentSetChangeSlot != nullptr) { // Get set change slot and then remove reference. int setChangeIndex = currentSetChangeSlot->getSlotCode(); currentSetChangeSlot = nullptr; // Ensure that a change to the current set is not attempted. if (setChangeIndex != m_originset) { emit released(m_index_sdl); emit setChangeActivated(setChangeIndex); } } } /** * @brief Calculate mouse movement coordinates for mouse movement slots * currently active. */ void JoyButton::mouseEvent() { JoyButtonSlot *buttonslot = nullptr; bool singleShot = false; if (currentMouseEvent != nullptr) { buttonslot = currentMouseEvent; singleShot = true; } if ((buttonslot != nullptr) || !mouseEventQueue.isEmpty()) { updateMouseParams(true, true, 0.0); QQueue tempQueue; if (buttonslot == nullptr) buttonslot = mouseEventQueue.dequeue(); int timeElapsed = testOldMouseTime.elapsed(); // Presumed initial mouse movement. Use full duration rather than // partial. if (staticMouseEventTimer.interval() < GlobalVariables::JoyButton::mouseRefreshRate) { timeElapsed = GlobalVariables::JoyButton::mouseRefreshRate + (timeElapsed - staticMouseEventTimer.interval()); } while (buttonslot != nullptr) { QElapsedTimer *mouseInterval = buttonslot->getMouseInterval(); int mousedirection = buttonslot->getSlotCode(); JoyButton::JoyMouseMovementMode mousemode = getMouseMode(); bool isActive = getActiveSlots().contains(buttonslot); if (isActive) { int mousespeed = 0; if (mousemode == JoyButton::MouseCursor) { switch (mousedirection) { case 1: case 2: mousespeed = mouseSpeedY; break; case 3: case 4: mousespeed = mouseSpeedX; break; } double difference = getMouseDistanceFromDeadZone(); double mouse1 = 0; double mouse2 = 0; double sumDist = buttonslot->getMouseDistance(); JoyMouseCurve currentCurve = getMouseCurve(); switch (currentCurve) { case QuadraticCurve: { difference = difference * difference; break; } case CubicCurve: { difference = difference * difference * difference; break; } case QuadraticExtremeCurve: { double temp = difference; difference = difference * difference; difference = (temp >= 0.95) ? (difference * 1.5) : difference; break; } case PowerCurve: { double tempsensitive = qMin(qMax(sensitivity, 1.0e-3), 1.0e+3); double temp = qMin(qMax(pow(difference, 1.0 / tempsensitive), 0.0), 1.0); difference = temp; break; } case EnhancedPrecisionCurve: { // Perform different forms of acceleration depending on // the range of the element from its assigned dead zone. // Useful for more precise controls with an axis. double temp = difference; if (temp <= 0.4) { // Low slope value for really slow acceleration difference = (difference * 0.37); } else if (temp <= 0.75) { // Perform Linear accleration with an appropriate // offset. difference = (difference - 0.252); } else { // Perform mouse acceleration. Make up the difference // due to the previous two segments. Maxes out at 1.0. difference = (difference * 2.008) - 1.008; } break; } case EasingQuadraticCurve: case EasingCubicCurve: { // Perform different forms of acceleration depending on // the range of the element from its assigned dead zone. // Useful for more precise controls with an axis. double temp = difference; if (temp <= 0.4) { // Low slope value for really slow acceleration difference = (difference * 0.38); // Out of high end. Reset easing status. if (buttonslot->isEasingActive()) { buttonslot->setEasingStatus(false); buttonslot->getEasingTime()->restart(); } } else if (temp <= 0.75) { // Perform Linear accleration with an appropriate // offset. difference = (difference - 0.248); // Out of high end. Reset easing status. if (buttonslot->isEasingActive()) { buttonslot->setEasingStatus(false); buttonslot->getEasingTime()->restart(); } } else { // Gradually increase the mouse speed until the specified elapsed duration // time has passed. int easingElapsed = buttonslot->getEasingTime()->elapsed(); double easingDuration = m_easingDuration; // Time in seconds if (!buttonslot->isEasingActive()) { buttonslot->setEasingStatus(true); buttonslot->getEasingTime()->restart(); easingElapsed = 0; } // Determine the multiplier to use for the current maximum mouse speed // based on how much time has passed. double elapsedDiff; if ((easingDuration > 0.0) && ((easingElapsed * .001) < easingDuration)) { elapsedDiff = ((easingElapsed * .001) / easingDuration); if (currentCurve == EasingQuadraticCurve) { elapsedDiff = (1.5 - 1.0) * elapsedDiff * elapsedDiff + 1.0; } else { elapsedDiff = (1.5 - 1.0) * (elapsedDiff * elapsedDiff * elapsedDiff) + 1.0; } } else { elapsedDiff = 1.5; } // Allow gradient control on the high end of an axis. difference = (elapsedDiff * difference); difference = (difference * 1.33067 - 0.496005); } break; } default: break; } double distance = 0; difference = (GlobalVariables::JoyButton::mouseSpeedModifier == 1.0) ? difference : (difference * GlobalVariables::JoyButton::mouseSpeedModifier); double mintravel = minMouseDistanceAccelThreshold * 0.01; double minstop = qMax(0.05, mintravel); // Last check ensures that acceleration is only applied for the same direction. if (extraAccelerationEnabled && isPartRealAxis() && (fabs(getAccelerationDistance() - lastAccelerationDistance) >= mintravel) && (((getAccelerationDistance() - lastAccelerationDistance) >= 0) == (getAccelerationDistance() >= 0))) { double magfactor = extraAccelerationMultiplier; double minfactor = qMax((GlobalVariables::JoyButton::DEFAULTSTARTACCELMULTIPLIER * 0.001) + 1.0, magfactor * (startAccelMultiplier * 0.01)); double maxtravel = maxMouseDistanceAccelThreshold * 0.01; double slope = (magfactor - minfactor) / (maxtravel - mintravel); double intercept = minfactor - (slope * mintravel); double intermediateTravel = qMin(maxtravel, fabs(getAccelerationDistance() - lastAccelerationDistance)); if ((currentAccelMulti > 1.0) && (oldAccelMulti == 0.0)) { intermediateTravel = qMin(maxtravel, intermediateTravel + mintravel); } double currentAccelMultiTemp = (slope * intermediateTravel + intercept); if (extraAccelCurve == EaseOutSineCurve) { double getMultiDiff2 = ((currentAccelMultiTemp - minfactor) / (extraAccelerationMultiplier - minfactor)); currentAccelMultiTemp = (extraAccelerationMultiplier - minfactor) * sin(getMultiDiff2 * (GlobalVariables::JoyControlStick::PI / 2.0)) + minfactor; } else if (extraAccelCurve == EaseOutQuadAccelCurve) { double getMultiDiff2 = ((currentAccelMultiTemp - minfactor) / (extraAccelerationMultiplier - minfactor)); currentAccelMultiTemp = -(extraAccelerationMultiplier - minfactor) * (getMultiDiff2 * (getMultiDiff2 - 2)) + minfactor; } else if (extraAccelCurve == EaseOutCubicAccelCurve) { double getMultiDiff = ((currentAccelMultiTemp - minfactor) / (extraAccelerationMultiplier - minfactor)) - 1; currentAccelMultiTemp = (extraAccelerationMultiplier - minfactor) * ((getMultiDiff) * (getMultiDiff) * (getMultiDiff) + 1) + minfactor; } difference = difference * currentAccelMultiTemp; currentAccelMulti = currentAccelMultiTemp; updateOldAccelMulti = currentAccelMulti; accelTravel = intermediateTravel; accelExtraDurationTime.restart(); } else if (extraAccelerationEnabled && isPartRealAxis() && (accelDuration > 0.0) && (currentAccelMulti > 0.0) && (fabs(getAccelerationDistance() - startingAccelerationDistance) < minstop)) { qDebug() << "Keep Trying: " << fabs(getAccelerationDistance() - lastAccelerationDistance); qDebug() << "MIN TRAVEL: " << mintravel; updateStartingMouseDistance = true; double magfactor = extraAccelerationMultiplier; double minfactor = qMax((GlobalVariables::JoyButton::DEFAULTSTARTACCELMULTIPLIER * 0.001) + 1.0, magfactor * (startAccelMultiplier * 0.01)); double maxtravel = maxMouseDistanceAccelThreshold * 0.01; double slope = (magfactor - minfactor) / (maxtravel - mintravel); double intercept = minfactor - (slope * mintravel); int elapsedElapsed = accelExtraDurationTime.elapsed(); double intermediateTravel = accelTravel; if (((getAccelerationDistance() - startingAccelerationDistance) >= 0) != (getAccelerationDistance() >= 0)) { // Travelling towards dead zone. Decrease acceleration and duration. intermediateTravel = qMax(intermediateTravel - fabs(getAccelerationDistance() - startingAccelerationDistance), mintravel); } // Linear case double currentAccelMultiTemp = (slope * intermediateTravel + intercept); double elapsedDuration = accelDuration * ((currentAccelMultiTemp - minfactor) / (extraAccelerationMultiplier - minfactor)); switch (extraAccelCurve) { case EaseOutSineCurve: { double multiDiff = ((currentAccelMultiTemp - minfactor) / (extraAccelerationMultiplier - minfactor)); double temp = sin(multiDiff * (GlobalVariables::JoyControlStick::PI / 2.0)); elapsedDuration = accelDuration * temp + 0; currentAccelMultiTemp = (extraAccelerationMultiplier - minfactor) * sin(multiDiff * (GlobalVariables::JoyControlStick::PI / 2.0)) + minfactor; break; } case EaseOutQuadAccelCurve: { double getMultiDiff2 = ((currentAccelMultiTemp - minfactor) / (extraAccelerationMultiplier - minfactor)); double temp = (getMultiDiff2 * (getMultiDiff2 - 2)); elapsedDuration = -accelDuration * temp + 0; currentAccelMultiTemp = -(extraAccelerationMultiplier - minfactor) * temp + minfactor; break; } case EaseOutCubicAccelCurve: { double getMultiDiff = ((currentAccelMultiTemp - minfactor) / (extraAccelerationMultiplier - minfactor)) - 1; double temp = ((getMultiDiff) * (getMultiDiff) * (getMultiDiff) + 1); elapsedDuration = accelDuration * temp + 0; currentAccelMultiTemp = (extraAccelerationMultiplier - minfactor) * temp + minfactor; break; } default: { break; } } double tempAccel = currentAccelMultiTemp; double elapsedDiff; if ((elapsedDuration > 0.0) && ((elapsedElapsed * 0.001) < elapsedDuration)) { elapsedDiff = ((elapsedElapsed * 0.001) / elapsedDuration); elapsedDiff = (1.0 - tempAccel) * (elapsedDiff * elapsedDiff * elapsedDiff) + tempAccel; difference = elapsedDiff * difference; // As acceleration is applied, do not update last // distance values when not necessary. updateStartingMouseDistance = false; updateOldAccelMulti = currentAccelMulti; } else { currentAccelMulti = 0.0; updateOldAccelMulti = 0.0; accelTravel = 0.0; } } else if (extraAccelerationEnabled && isPartRealAxis()) { currentAccelMulti = 0.0; updateStartingMouseDistance = true; oldAccelMulti = updateOldAccelMulti = 0.0; accelTravel = 0.0; } sumDist += difference * (mousespeed * GlobalVariables::JoyButtonSlot::JOYSPEED * timeElapsed) * 0.001; distance = sumDist; switch (mousedirection) { case 1: mouse2 = -distance; break; case 2: mouse2 = distance; break; case 3: mouse1 = -distance; break; case 4: mouse1 = distance; break; } mouseCursorInfo infoX; infoX.code = mouse1; infoX.slot = buttonslot; cursorXSpeeds.append(infoX); mouseCursorInfo infoY; infoY.code = mouse2; infoY.slot = buttonslot; cursorYSpeeds.append(infoY); sumDist = 0; buttonslot->setDistance(sumDist); } else if (mousemode == JoyButton::MouseSpring) { double mouse1 = -2.0; double mouse2 = -2.0; double difference = getMouseDistanceFromDeadZone(); switch (mousedirection) { case 1: setDistanceForSpring(mouseHelper, mouse1, mouse2, -difference); break; case 2: setDistanceForSpring(mouseHelper, mouse1, mouse2, difference); break; case 3: setDistanceForSpring(mouseHelper, mouse2, mouse1, -difference); break; case 4: setDistanceForSpring(mouseHelper, mouse2, mouse1, difference); break; } updateMouseProperties(mouse1, 0.0, springWidth, springHeight, relativeSpring, GlobalVariables::JoyButton::springModeScreen, springXSpeeds, 'X'); updateMouseProperties(mouse2, 0.0, springWidth, springHeight, relativeSpring, GlobalVariables::JoyButton::springModeScreen, springYSpeeds, 'Y'); mouseInterval->restart(); } tempQueue.enqueue(buttonslot); } if (!mouseEventQueue.isEmpty() && !singleShot) buttonslot = mouseEventQueue.dequeue(); else buttonslot = nullptr; } if (!tempQueue.isEmpty()) { while (!tempQueue.isEmpty()) { JoyButtonSlot *tempslot = tempQueue.dequeue(); mouseEventQueue.enqueue(tempslot); } } } } void JoyButton::setDistanceForSpring(JoyButtonMouseHelper &mouseHelper, double &mouseFirstAx, double &mouseSecondAx, double distanceFromDeadZone) { if (mouseHelper.getFirstSpringStatus()) { mouseFirstAx = 0.0; mouseHelper.setFirstSpringStatus(false); } mouseSecondAx = distanceFromDeadZone; } void JoyButton::updateMouseProperties(double newAxisValue, double newSpringDead, int newSpringWidth, int newSpringHeight, bool relatived, int modeScreen, QList &springSpeeds, QChar axis, double newAxisValueY, double newSpringDeadY) { PadderCommon::springModeInfo axisInfo; if (axis == 'X') { axisInfo.displacementX = newAxisValue; axisInfo.springDeadX = newSpringDead; } else if (axis == 'Y') { axisInfo.displacementY = newAxisValue; axisInfo.springDeadY = newSpringDead; } else { axisInfo.displacementX = newAxisValue; axisInfo.springDeadX = newSpringDead; axisInfo.displacementY = newAxisValueY; axisInfo.springDeadY = newSpringDeadY; } axisInfo.width = newSpringWidth; axisInfo.height = newSpringHeight; axisInfo.relative = relatived; axisInfo.screen = modeScreen; springSpeeds.append(axisInfo); } void JoyButton::wheelEventVertical() { JoyButtonSlot *buttonslot = nullptr; if (currentWheelVerticalEvent != nullptr) buttonslot = currentWheelVerticalEvent; if (buttonslot && (wheelSpeedY != 0)) { bool isActive = getActiveSlots().contains(buttonslot); if (isActive) { sendevent(buttonslot, true); sendevent(buttonslot, false); mouseWheelVerticalEventQueue.enqueue(buttonslot); mouseWheelVerticalEventTimer.start(1000 / wheelSpeedY); } else { mouseWheelVerticalEventTimer.stop(); } } else if (!mouseWheelVerticalEventQueue.isEmpty() && (wheelSpeedY != 0)) { QQueue tempQueue; while (!mouseWheelVerticalEventQueue.isEmpty()) { buttonslot = mouseWheelVerticalEventQueue.dequeue(); bool isActive = getActiveSlots().contains(buttonslot); if (isActive) { sendevent(buttonslot, true); sendevent(buttonslot, false); tempQueue.enqueue(buttonslot); } } if (!tempQueue.isEmpty()) { mouseWheelVerticalEventQueue = tempQueue; mouseWheelVerticalEventTimer.start(1000 / wheelSpeedY); } else { mouseWheelVerticalEventTimer.stop(); } } else { mouseWheelVerticalEventTimer.stop(); } } void JoyButton::wheelEventHorizontal() { JoyButtonSlot *buttonslot = nullptr; if (currentWheelHorizontalEvent != nullptr) buttonslot = currentWheelHorizontalEvent; if (buttonslot && (wheelSpeedX != 0)) { bool isActive = getActiveSlots().contains(buttonslot); if (isActive) { sendevent(buttonslot, true); sendevent(buttonslot, false); mouseWheelHorizontalEventQueue.enqueue(buttonslot); mouseWheelHorizontalEventTimer.start(1000 / wheelSpeedX); } else { mouseWheelHorizontalEventTimer.stop(); } } else if (!mouseWheelHorizontalEventQueue.isEmpty() && (wheelSpeedX != 0)) { QQueue tempQueue; while (!mouseWheelHorizontalEventQueue.isEmpty()) { buttonslot = mouseWheelHorizontalEventQueue.dequeue(); bool isActive = getActiveSlots().contains(buttonslot); if (isActive) { sendevent(buttonslot, true); sendevent(buttonslot, false); tempQueue.enqueue(buttonslot); } } if (!tempQueue.isEmpty()) { mouseWheelHorizontalEventQueue = tempQueue; mouseWheelHorizontalEventTimer.start(1000 / wheelSpeedX); } else { mouseWheelHorizontalEventTimer.stop(); } } else { mouseWheelHorizontalEventTimer.stop(); } } void JoyButton::setUseTurbo(bool useTurbo) { bool initialState = m_useTurbo; if (useTurbo != m_useTurbo) { if (useTurbo && this->containsSequence()) m_useTurbo = false; else m_useTurbo = useTurbo; if (initialState != m_useTurbo) { emit turboChanged(m_useTurbo); emit propertyUpdated(); if (m_useTurbo && (this->turboInterval == 0)) this->setTurboInterval(GlobalVariables::JoyButton::ENABLEDTURBODEFAULT); } } } bool JoyButton::isUsingTurbo() { return m_useTurbo; } QString JoyButton::getXmlName() { return GlobalVariables::JoyButton::xmlName; } QString JoyButton::getName(bool forceFullFormat, bool displayNames) { QString newlabel = getPartialName(forceFullFormat, displayNames); // qDebug() << "partial name is: " << newlabel; newlabel.append(": "); // qDebug() << "actionName is " << actionName; if (!actionName.isEmpty() && displayNames) newlabel.append(actionName); else newlabel.append(getCalculatedActiveZoneSummary()); // qDebug() << "name in getName(bool forceFullFormat, bool displayNames) is now: " << newlabel; return newlabel; } QString JoyButton::getPartialName(bool forceFullFormat, bool displayNames) const { QString temp = QString(); if (!buttonName.isEmpty() && displayNames) { if (forceFullFormat) temp.append(tr("Button")).append(" "); temp.append(buttonName); } else if (!defaultButtonName.isEmpty()) { if (forceFullFormat) temp.append(tr("Button")).append(" "); temp.append(defaultButtonName); } else { temp.append(tr("Button")).append(" ").append(QString::number(getRealJoyNumber())); } return temp; } /** * @brief Generate a string representing a summary of the slots currently * assigned to a button * @return String of currently assigned slots */ QString JoyButton::getSlotsSummary() { QString newlabel = QString(); int slotCount = getAssignedSlots()->size(); if (slotCount > 0) { QListIterator iter(*getAssignedSlots()); QStringList stringlist = QStringList(); int i = 0; while (iter.hasNext()) { JoyButtonSlot *slot = iter.next(); stringlist.append(slot->getSlotString()); i++; if ((i > 4) && iter.hasNext()) { stringlist.append(" ..."); iter.toBack(); } } newlabel = stringlist.join(", "); } else { newlabel = newlabel.append(tr("[NO KEY]")); } return newlabel; } /** * @brief Generate a string that represents slots that will be activated or * slots that are currently active if a button is pressed * @return String of currently applicable slots for a button */ QString JoyButton::getActiveZoneSummary() { QList tempList = getActiveZoneList(); return buildActiveZoneSummary(tempList); } QString JoyButton::getCalculatedActiveZoneSummary() { QString temp = QString(); lockForWritedString(temp, activeZoneString); return temp; } /** * @brief Generate active zone string and notify other objects. */ void JoyButton::buildActiveZoneSummaryString() { lockForWritedString(activeZoneString, getActiveZoneSummary()); qDebug() << "activeZoneString after getActiveZoneSummary() is: " << activeZoneString; emit activeZoneChanged(); } /** * @brief Generate active zone string but do not notify any other object. */ void JoyButton::localBuildActiveZoneSummaryString() { lockForWritedString(activeZoneString, getActiveZoneSummary()); } QString JoyButton::buildActiveZoneSummary(QList &tempList) { QString newlabel = QString(); QListIterator iter(tempList); QListIterator *iterMain(&iter); QStringList stringlist = QStringList(); QStringList stringListMix = QStringList(); int i = 0; int j = 0; bool slotsActive = !getActiveSlots().isEmpty(); if (setSelectionCondition == SetChangeOneWay) { newlabel.append(tr("[Set %1 1W]").arg(setSelection + 1)); if (iterMain->hasNext()) newlabel.append(" "); } else if (setSelectionCondition == SetChangeTwoWay) { newlabel = newlabel.append(tr("[Set %1 2W]").arg(setSelection + 1)); if (iterMain->hasNext()) newlabel.append(" "); } if (setSelectionCondition == SetChangeWhileHeld) { newlabel.append(tr("[Set %1 WH]").arg(setSelection + 1)); } else if (iterMain->hasNext()) { bool behindHold = false; while (iterMain->hasNext()) { JoyButtonSlot *slot = iterMain->next(); JoyButtonSlot::JoySlotInputAction mode = slot->getSlotMode(); if (mode == JoyButtonSlot::JoySlotInputAction::JoyMix) { QListIterator iterMini(*slot->getMixSlots()); QListIterator *iterM(&iterMini); while (iterM->hasNext()) { JoyButtonSlot *slotMini = iterM->next(); JoyButtonSlot::JoySlotInputAction modeMini = slotMini->getSlotMode(); qDebug() << "modeMini is " << modeMini; qDebug() << "slotsActive are empty? " << slotsActive; buildActiveZoneSummarySwitchSlots(modeMini, slotMini, behindHold, &stringListMix, j, iterM, slotsActive); stringListMix.append("+"); qDebug() << "Create summary for JoyMix. Progress: " << stringListMix; } j = 0; i++; if (!stringListMix.isEmpty()) { if (stringListMix.last() == '+') stringListMix.removeLast(); qDebug() << "Create summary for JoyMix. Progress: " << stringListMix; QString res = ""; for (const QString &strListEl : stringListMix) res += strListEl; stringlist.append(res); stringListMix.clear(); } else { stringlist.append(slot->getTextData()); stringListMix.clear(); } behindHold = false; } else { buildActiveZoneSummarySwitchSlots(mode, slot, behindHold, &stringlist, i, iterMain, slotsActive); } if ((i > 4) && iterMain->hasNext()) { stringlist.append(" ..."); iterMain->toBack(); } } newlabel.append(stringlist.join(", ")); } else if (setSelectionCondition == SetChangeDisabled) { newlabel.append(tr("[NO KEY]")); } qDebug() << "NEW LABEL IS: " << newlabel; qDebug() << "i: " << i; qDebug() << "j: " << j; return newlabel; } void JoyButton::buildActiveZoneSummarySwitchSlots(JoyButtonSlot::JoySlotInputAction mode, JoyButtonSlot *slot, bool &behindHold, QStringList *stringlist, int &i, QListIterator *iter, bool slotsActive) { switch (mode) { case JoyButtonSlot::JoyKeyboard: case JoyButtonSlot::JoyMouseButton: case JoyButtonSlot::JoyMouseMovement: { QString temp = slot->getSlotString(); if (behindHold) { temp.prepend("[H] "); behindHold = false; } stringlist->append(temp); i++; break; } case JoyButtonSlot::JoyKeyPress: { // Skip slot if a press time slot was inserted. break; } case JoyButtonSlot::JoyHold: { if (!slotsActive && (i == 0)) { // If button is not active and first slot is a hold, // keep processing slots but take note of the hold. behindHold = true; } else { // Move iter to back so loop will end. iter->toBack(); } break; } case JoyButtonSlot::JoyLoadProfile: case JoyButtonSlot::JoySetChange: case JoyButtonSlot::JoyTextEntry: case JoyButtonSlot::JoyExecute: { QString temp = slot->getSlotString(); if (behindHold) { temp.prepend("[H] "); behindHold = false; } stringlist->append(temp); i++; break; } case JoyButtonSlot::JoyRelease: { if (currentRelease == nullptr) findJoySlotsEnd(iter); break; } case JoyButtonSlot::JoyDistance: { iter->toBack(); break; } case JoyButtonSlot::JoyDelay: { iter->toBack(); break; } case JoyButtonSlot::JoyCycle: { iter->toBack(); break; } default: if (mode > 15 || mode < 0) { QString temp = slot->getSlotString(); if (behindHold) { temp.prepend("[H] "); behindHold = false; } stringlist->append(temp); i++; break; } break; } } QList JoyButton::getActiveZoneList() { QListIterator activeSlotsIter(getActiveSlots()); QListIterator assignmentsIter(*getAssignedSlots()); QListIterator *iter = nullptr; QReadWriteLock *tempLock = nullptr; qDebug() << "Active slots are: "; int x, y; x = 0; y = 0; for (auto actSlot : getActiveSlots()) { x++; qDebug() << x << ") " << actSlot->getSlotString(); } qDebug() << "Assigned slots are: "; for (auto assignedSlot : *getAssignedSlots()) { y++; qDebug() << y << ") " << assignedSlot->getSlotString(); } activeZoneLock.lockForRead(); int numActiveSlots = getActiveSlots().size(); activeZoneLock.unlock(); if (numActiveSlots > 0) { tempLock = &activeZoneLock; iter = &activeSlotsIter; } else { tempLock = &assignmentsLock; iter = &assignmentsIter; } QReadLocker tempLocker(tempLock); Q_UNUSED(tempLocker); if (tempLock == &assignmentsLock) { if (previousCycle != nullptr) { qDebug() << "if there exists previous Cycle, find it in activeSlots"; iter->findNext(previousCycle); } } QList tempSlotList; if ((setSelectionCondition != SetChangeWhileHeld) && iter->hasNext()) { while (iter->hasNext()) { JoyButtonSlot *slot = iter->next(); JoyButtonSlot::JoySlotInputAction mode = slot->getSlotMode(); switch (mode) { case JoyButtonSlot::JoyKeyboard: case JoyButtonSlot::JoyMouseButton: case JoyButtonSlot::JoyMouseMovement: case JoyButtonSlot::JoyKeyPress: case JoyButtonSlot::JoyHold: case JoyButtonSlot::JoyLoadProfile: case JoyButtonSlot::JoySetChange: case JoyButtonSlot::JoyTextEntry: case JoyButtonSlot::JoyExecute: case JoyButtonSlot::JoyMix: { tempSlotList.append(slot); break; } case JoyButtonSlot::JoyRelease: { if (currentRelease == nullptr) findJoySlotsEnd(iter); break; } case JoyButtonSlot::JoyDistance: case JoyButtonSlot::JoyCycle: { iter->toBack(); break; } default: { break; } } } } return tempSlotList; } /** * @brief Generate a string representing all the currently assigned slots for * a button * @return String representing all assigned slots for a button */ QString JoyButton::getSlotsString() { QString label = QString(); if (getAssignedSlots()->size() > 0) { qDebug() << "There is more assignments than 0 in getSlotsString(): " << getAssignedSlots()->count(); QListIterator iter(*getAssignedSlots()); QStringList stringlist = QStringList(); while (iter.hasNext()) { JoyButtonSlot *slot = iter.next(); qDebug() << "deviceCode = " << slot->getSlotCode(); qDebug() << "slotMode = " << slot->getSlotMode(); QString slotString = slot->getSlotString(); if (slotString == tr("[NO KEY]")) { qDebug() << "EMPTY ASSIGNED SLOT"; } stringlist.append(slotString); // tu } label = stringlist.join(", "); } else { qDebug() << "There is no assignments for button in getSlotsString()"; label = label.append(tr("[NO KEY]")); } return label; } void JoyButton::setCustomName(QString name) { customName = name; } QString JoyButton::getCustomName() { return customName; } /** * @brief Create new JoyButtonSlot with data provided and append the new slot * an existing to the assignment list. * @param Native virtual code being used. * @param Mode of the slot. * @return Whether the new slot was successfully added to the assignment list. */ bool JoyButton::setAssignedSlot(int code, JoyButtonSlot::JoySlotInputAction mode) { bool slotInserted = false; JoyButtonSlot *slot = new JoyButtonSlot(code, mode, this); if (slot->getSlotMode() == JoyButtonSlot::JoyDistance && (slot->getSlotCode() >= 1) && (slot->getSlotCode() <= 100) && (getTotalSlotDistance(slot) <= 1.0)) { assignmentsLock.lockForWrite(); getAssignmentsLocal().append(slot); assignmentsLock.unlock(); buildActiveZoneSummaryString(); slotInserted = true; } else if (slot->getSlotCode() >= 0) { assignmentsLock.lockForWrite(); getAssignmentsLocal().append(slot); assignmentsLock.unlock(); buildActiveZoneSummaryString(); slotInserted = true; } if (slotInserted) { checkTurboCondition(slot); emit slotsChanged(); } else if (slot != nullptr) { slot->deleteLater(); slot = nullptr; } return slotInserted; } /** * @brief Create new JoyButtonSlot with data provided and append the new slot * an existing to the assignment list. * @param Native virtual code being used. * @param Qt key alias used for abstracting native virtual code. * @param Mode of the slot. * @return Whether the new slot was successfully added to the assignment list. */ bool JoyButton::setAssignedSlot(int code, int alias, JoyButtonSlot::JoySlotInputAction mode) { bool slotInserted = false; JoyButtonSlot *slot = new JoyButtonSlot(code, alias, mode, this); if (slot->getSlotMode() == JoyButtonSlot::JoyDistance && (slot->getSlotCode() >= 1) && (slot->getSlotCode() <= 100) && (getTotalSlotDistance(slot) <= 1.0)) { assignmentsLock.lockForWrite(); getAssignmentsLocal().append(slot); assignmentsLock.unlock(); buildActiveZoneSummaryString(); slotInserted = true; } else if (slot->getSlotCode() >= 0) { assignmentsLock.lockForWrite(); getAssignmentsLocal().append(slot); assignmentsLock.unlock(); buildActiveZoneSummaryString(); slotInserted = true; } if (slotInserted) { checkTurboCondition(slot); emit slotsChanged(); } else if (slot != nullptr) { slot->deleteLater(); slot = nullptr; } return slotInserted; } /** * @brief Create new JoyButtonSlot with data provided and replace an existing * slot in the assignment list if one exists. * @param Native virtual code being used. * @param Qt key alias used for abstracting native virtual code. * @param Index number in the list. * @param Mode of the slot. * @return Whether the new slot was successfully added to the assignment list. */ bool JoyButton::setAssignedSlot(int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode) { bool permitSlot = true; JoyButtonSlot *slot = new JoyButtonSlot(code, alias, mode, this); if ((slot->getSlotMode() == JoyButtonSlot::JoyDistance) && (slot->getSlotCode() >= 1) && (slot->getSlotCode() <= 100)) { if (getTotalSlotDistance(slot) > 1.0) permitSlot = false; } else if (slot->getSlotCode() < 0) { permitSlot = false; } if (permitSlot) { assignmentsLock.lockForWrite(); if ((index >= 0) && (index < getAssignedSlots()->count())) { // Insert slot and move existing slots. JoyButtonSlot *temp = getAssignedSlots()->at(index); if (temp != nullptr) { temp->deleteLater(); temp = nullptr; } getAssignmentsLocal().replace(index, slot); } else if (index >= getAssignmentsLocal().count()) { // Append code into a new slot getAssignmentsLocal().append(slot); } checkTurboCondition(slot); assignmentsLock.unlock(); buildActiveZoneSummaryString(); emit slotsChanged(); } else if (slot != nullptr) { slot->deleteLater(); slot = nullptr; } return permitSlot; } /** * @brief Create new JoyButtonSlot with data provided and insert it into * assignments list if it is valid. * @param Native virtual code being used. * @param Qt key alias used for abstracting native virtual code. * @param Index number in the list. * @param Mode of the slot. * @return Whether the new slot was successfully added to the assignment list. */ bool JoyButton::insertAssignedSlot(int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode) { bool permitSlot = true; JoyButtonSlot *slot = new JoyButtonSlot(code, alias, mode, this); if (slot->getSlotMode() == JoyButtonSlot::JoyDistance && (slot->getSlotCode() >= 1) && (slot->getSlotCode() <= 100)) { if (getTotalSlotDistance(slot) > 1.0) permitSlot = false; } else if (slot->getSlotCode() < 0) { permitSlot = false; } if (permitSlot) { assignmentsLock.lockForWrite(); if ((index >= 0) && (index < getAssignedSlots()->count())) { // Insert new slot into list. Move old slots if needed. getAssignmentsLocal().insert(index, slot); } else if (index >= getAssignedSlots()->count()) { // Append new slot into list. getAssignmentsLocal().append(slot); } qDebug() << "assignments variable in joybutton has now: " << getAssignedSlots()->count() << " input slots"; checkTurboCondition(slot); assignmentsLock.unlock(); buildActiveZoneSummaryString(); emit slotsChanged(); } else if (slot != nullptr) { slot->deleteLater(); slot = nullptr; } return permitSlot; } bool JoyButton::insertAssignedSlot(JoyButtonSlot *newSlot, bool updateActiveString) { bool permitSlot = false; if ((newSlot->getSlotMode() == JoyButtonSlot::JoyDistance) && (newSlot->getSlotCode() >= 1) && (newSlot->getSlotCode() <= 100)) { if (getTotalSlotDistance(newSlot) <= 1.0) permitSlot = true; } else if ((newSlot->getSlotMode() == JoyButtonSlot::JoyTextEntry || newSlot->getSlotMode() == JoyButtonSlot::JoyExecute) && !newSlot->getTextData().isEmpty()) { permitSlot = true; } else if ((newSlot->getSlotMode() == JoyButtonSlot::JoyLoadProfile) || newSlot->getSlotCode() >= 0) { permitSlot = true; } if (permitSlot) { assignmentsLock.lockForWrite(); checkTurboCondition(newSlot); getAssignmentsLocal().append(newSlot); assignmentsLock.unlock(); if (updateActiveString) buildActiveZoneSummaryString(); emit slotsChanged(); } return permitSlot; } bool JoyButton::insertAssignedSlot(JoyButtonSlot *newSlot, int index, bool updateActiveString) { bool permitSlot = true; JoyButtonSlot *slot = new JoyButtonSlot(newSlot, this); if (slot->getSlotMode() == JoyButtonSlot::JoyDistance && (slot->getSlotCode() >= 1) && (slot->getSlotCode() <= 100)) { if (getTotalSlotDistance(slot) > 1.0) permitSlot = false; } else if (slot->getSlotCode() < 0) { permitSlot = false; } if (permitSlot) { assignmentsLock.lockForWrite(); if ((index >= 0) && (index < getAssignedSlots()->count())) { // Insert new slot into list. Move old slots if needed. getAssignmentsLocal().insert(index, slot); } else if (index >= getAssignedSlots()->count()) { // Append new slot into list. getAssignmentsLocal().append(slot); } qDebug() << "assignments variable in joybutton has now: " << getAssignedSlots()->count() << " input slots"; checkTurboCondition(slot); assignmentsLock.unlock(); buildActiveZoneSummaryString(); emit slotsChanged(); } else if (slot != nullptr) { /*if (slot->getSlotMode() == 15) { qDeleteAll(*slot->getMixSlots()); }*/ slot->deleteLater(); slot = nullptr; } return permitSlot; } bool JoyButton::setAssignedSlot(JoyButtonSlot *otherSlot, int index) { bool permitSlot = false; JoyButtonSlot *newslot = new JoyButtonSlot(otherSlot, this); if (newslot->getSlotMode() == JoyButtonSlot::JoyDistance && (newslot->getSlotCode() >= 1) && (newslot->getSlotCode() <= 100)) { if (getTotalSlotDistance(newslot) <= 1.0) permitSlot = true; } else if (newslot->getSlotMode() == JoyButtonSlot::JoyLoadProfile) { permitSlot = true; } else if (newslot->getSlotMode() == JoyButtonSlot::JoyMix && newslot->getMixSlots()->count() > 1) { permitSlot = true; } else if ((newslot->getSlotMode() == JoyButtonSlot::JoyExecute || newslot->getSlotMode() == JoyButtonSlot::JoyTextEntry) && !newslot->getTextData().isEmpty()) { permitSlot = true; } else if (newslot->getSlotCode() >= 0) { permitSlot = true; } if (permitSlot) { assignmentsLock.lockForWrite(); checkTurboCondition(newslot); if ((index >= 0) && (index < getAssignedSlots()->count())) { // Slot already exists. Override code and place into desired slot JoyButtonSlot *temp = getAssignedSlots()->at(index); if (temp->getSlotMode() == JoyButtonSlot::JoySlotInputAction::JoyMix) { for (auto minislot : *temp->getMixSlots()) { minislot->deleteLater(); minislot = nullptr; } delete temp->getMixSlots(); temp->assignMixSlotsToNull(); } if (temp != nullptr) { temp->deleteLater(); temp = nullptr; } getAssignmentsLocal().replace(index, newslot); } else if (index >= getAssignmentsLocal().count()) { // Append code into a new slot getAssignmentsLocal().append(newslot); } assignmentsLock.unlock(); buildActiveZoneSummaryString(); emit slotsChanged(); } else if (newslot != nullptr) { newslot->deleteLater(); newslot = nullptr; } return permitSlot; } QList *JoyButton::getAssignedSlots() { return &assignments; } QList const &JoyButton::getActiveSlots() { return activeSlots; } void JoyButton::setMouseSpeedX(int speed) { if ((speed >= 1) && (speed <= GlobalVariables::JoyButton::MAXMOUSESPEED)) { mouseSpeedX = speed; emit propertyUpdated(); } } int JoyButton::getMouseSpeedX() { return mouseSpeedX; } void JoyButton::setMouseSpeedY(int speed) { if ((speed >= 1) && (speed <= GlobalVariables::JoyButton::MAXMOUSESPEED)) { mouseSpeedY = speed; emit propertyUpdated(); } } int JoyButton::getMouseSpeedY() { return mouseSpeedY; } void JoyButton::setChangeSetSelection(int index, bool updateActiveString) { if ((index >= -1) && (index <= 7)) { setSelection = index; if (updateActiveString) buildActiveZoneSummaryString(); emit propertyUpdated(); } } int JoyButton::getSetSelection() { return setSelection; } void JoyButton::setChangeSetCondition(SetChangeCondition condition, bool passive, bool updateActiveString) { SetChangeCondition oldCondition = setSelectionCondition; if ((condition != setSelectionCondition) && !passive) { if ((condition == SetChangeWhileHeld) || (condition == SetChangeTwoWay)) { // Set new condition emit setAssignmentChanged(m_index_sdl, setSelection, condition); } else if ((setSelectionCondition == SetChangeWhileHeld) || (setSelectionCondition == SetChangeTwoWay)) { // Remove old condition emit setAssignmentChanged(m_index_sdl, setSelection, SetChangeDisabled); } setSelectionCondition = condition; } else if (passive) { setSelectionCondition = condition; } if (setSelectionCondition == SetChangeDisabled) setChangeSetSelection(-1); if (setSelectionCondition != oldCondition) { if (updateActiveString) buildActiveZoneSummaryString(); emit propertyUpdated(); } } JoyButton::SetChangeCondition JoyButton::getChangeSetCondition() { return setSelectionCondition; } /** * @brief Checks if this button is currently active * @returns True if the button is pressed, false otherwise */ bool JoyButton::getButtonState() { return isButtonPressed; } int JoyButton::getOriginSet() { return m_originset; } void JoyButton::pauseWaitEvent() { if (currentPause != nullptr) { if (!isButtonPressedQueue.isEmpty() && createDeskTimer.isActive()) { if (slotiter != nullptr) { slotiter->toBack(); bool lastIgnoreSetState = ignoreSetQueue.last(); bool lastIsButtonPressed = isButtonPressedQueue.last(); ignoreSetQueue.clear(); isButtonPressedQueue.clear(); ignoreSetQueue.enqueue(lastIgnoreSetState); isButtonPressedQueue.enqueue(lastIsButtonPressed); currentPause = nullptr; currentRelease = nullptr; releaseDeskTimer.stop(); pauseWaitTimer.stop(); slotiter->toFront(); if (previousCycle != nullptr) slotiter->findNext(previousCycle); quitEvent = true; keyPressHold.restart(); } } } if (currentPause != nullptr) { // If release timer is active, temporarily // disable it if (releaseDeskTimer.isActive()) releaseDeskTimer.stop(); if (inpauseHold.elapsed() < currentPause->getSlotCode()) { startTimerOverrun(currentPause->getSlotCode(), &inpauseHold, &pauseWaitTimer, 0); } else { pauseWaitTimer.stop(); createDeskTimer.stop(); currentPause = nullptr; createDeskEvent(); // If release timer was disabled but if the button // is not pressed, restart the release timer. if (!releaseDeskTimer.isActive() && (isButtonPressedQueue.isEmpty() || !isButtonPressedQueue.last())) waitForReleaseDeskEvent(); } } else { pauseWaitTimer.stop(); } } void JoyButton::checkForSetChange() { if (!ignoreSetQueue.isEmpty() && !isButtonPressedQueue.isEmpty()) { bool tempFinalState = isButtonPressedQueue.last(); bool tempFinalIgnoreSetsState = ignoreSetQueue.last(); if (!tempFinalIgnoreSetsState) { if (!tempFinalState && (setSelectionCondition == SetChangeOneWay) && (setSelection > -1)) { restartAllForSetChange(); } else if (!tempFinalState && (setSelectionCondition == SetChangeTwoWay) && (setSelection > -1)) { restartAllForSetChange(); } else if ((setSelectionCondition == SetChangeWhileHeld) && (setSelection > -1)) { if (tempFinalState) whileHeldStatus = true; else whileHeldStatus = false; restartAllForSetChange(); } } // Clear queue except for a press if it is last in if (!isButtonPressedQueue.isEmpty()) { isButtonPressedQueue.clear(); if (tempFinalState) isButtonPressedQueue.enqueue(tempFinalState); } // Clear queue except for a press if it is last in if (!ignoreSetQueue.isEmpty()) { bool tempFinalIgnoreSetsState_local = ignoreSetQueue.last(); ignoreSetQueue.clear(); if (tempFinalState) ignoreSetQueue.enqueue(tempFinalIgnoreSetsState_local); } } } void JoyButton::restartAllForSetChange() { if (createDeskTimer.isActive()) createDeskTimer.stop(); if (releaseDeskTimer.isActive()) releaseDeskTimer.stop(); isButtonPressedQueue.clear(); ignoreSetQueue.clear(); emit released(m_index_sdl); emit setChangeActivated(setSelection); } void JoyButton::waitForDeskEvent() { if (quitEvent && !isButtonPressedQueue.isEmpty() && isButtonPressedQueue.last()) { if (createDeskTimer.isActive()) { keyPressTimer.stop(); createDeskTimer.stop(); releaseDeskTimer.stop(); createDeskEvent(); } else { keyPressTimer.stop(); releaseDeskTimer.stop(); createDeskEvent(); } } else if (!createDeskTimer.isActive()) { #ifdef Q_CC_MSVC createDeskTimer.start(5); releaseDeskTimer.stop(); #else createDeskTimer.start(0); releaseDeskTimer.stop(); #endif } else if (createDeskTimer.isActive()) { // Decrease timer interval of active timer. createDeskTimer.start(0); releaseDeskTimer.stop(); } } void JoyButton::waitForReleaseDeskEvent() { if (quitEvent && !keyPressTimer.isActive()) { if (releaseDeskTimer.isActive()) releaseDeskTimer.stop(); createDeskTimer.stop(); keyPressTimer.stop(); releaseDeskEvent(); } else if (!releaseDeskTimer.isActive()) { #ifdef Q_CC_MSVC releaseDeskTimer.start(1); createDeskTimer.stop(); #else releaseDeskTimer.start(1); createDeskTimer.stop(); #endif } else if (releaseDeskTimer.isActive()) { createDeskTimer.stop(); } } bool JoyButton::containsSequence() { bool result = false; assignmentsLock.lockForRead(); QListIterator tempiter(*getAssignedSlots()); while (tempiter.hasNext()) { JoyButtonSlot *slot = tempiter.next(); JoyButtonSlot::JoySlotInputAction mode = slot->getSlotMode(); if ((mode == JoyButtonSlot::JoyPause) || (mode == JoyButtonSlot::JoyHold) || (mode == JoyButtonSlot::JoyDistance)) { result = true; tempiter.toBack(); } } assignmentsLock.unlock(); return result; } void JoyButton::holdEvent() { if (currentHold != nullptr) { bool currentlyPressed = false; if (!isButtonPressedQueue.isEmpty()) currentlyPressed = isButtonPressedQueue.last(); // Activate hold event if (currentlyPressed && (buttonHold.elapsed() > currentHold->getSlotCode())) { qDebug() << buttonHold.elapsed() << " > " << currentHold->getSlotCode(); qDebug() << "Activate hold event"; releaseActiveSlots(); currentHold = nullptr; holdTimer.stop(); buttonHold.restart(); createDeskEvent(); } // Elapsed time has not occurred else if (currentlyPressed) { qDebug() << "Elapsed time has not occurred, because buttonHold: " << buttonHold.elapsed() << " is not greater than currentHoldCode: " << currentHold->getSlotCode(); startTimerOverrun(currentHold->getSlotCode(), &buttonHold, &holdTimer); } // Pre-emptive release else { qDebug() << "Hold button is not pressed"; currentHold = nullptr; holdTimer.stop(); if (slotiter != nullptr) { qDebug() << "slotiter exists"; findJoySlotsEnd(slotiter); createDeskEvent(); } } } else { holdTimer.stop(); } } void JoyButton::startTimerOverrun(int slotCode, QElapsedTimer *currSlotTime, QTimer *currSlotTimer, bool releasedDeskTimer) { int proposedInterval = slotCode - currSlotTime->elapsed(); proposedInterval = (proposedInterval > 0) ? proposedInterval : 0; int newTimerInterval = qMin(10, proposedInterval); currSlotTimer->start(newTimerInterval); if (releasedDeskTimer) { // If release timer is active, push next run until // after keyDelayTimer will timeout again. Helps // reduce CPU usage of an excessively repeating timer. if (releaseDeskTimer.isActive()) releaseDeskTimer.start(proposedInterval); } } void JoyButton::delayEvent() { if (currentDelay != nullptr) { bool currentlyPressed = false; if (!isButtonPressedQueue.isEmpty()) currentlyPressed = isButtonPressedQueue.last(); if ((currentDelay != nullptr) && (buttonDelay.elapsed() > currentDelay->getSlotCode())) { // Delay time has elapsed. Continue processing slots. currentDelay = nullptr; delayTimer.stop(); buttonDelay.restart(); createDeskEvent(); } else if (currentlyPressed) { // Elapsed time has not occurred startTimerOverrun(currentDelay->getSlotCode(), &buttonDelay, &delayTimer); } else { // Pre-emptive release currentDelay = nullptr; delayTimer.stop(); } } else { delayTimer.stop(); } } void JoyButton::releaseDeskEvent(bool skipsetchange) { quitEvent = false; pauseWaitTimer.stop(); holdTimer.stop(); createDeskTimer.stop(); keyPressTimer.stop(); delayTimer.stop(); setChangeTimer.stop(); releaseActiveSlots(); if (!isButtonPressedQueue.isEmpty() && (currentRelease == nullptr)) releaseSlotEvent(); else currentRelease = nullptr; if (!skipsetchange && (setSelectionCondition != SetChangeDisabled) && !isButtonPressedQueue.isEmpty() && (currentRelease == nullptr)) { bool tempButtonPressed = isButtonPressedQueue.last(); bool tempFinalIgnoreSetsState = ignoreSetQueue.last(); if (!tempButtonPressed && !tempFinalIgnoreSetsState) { if ((setSelectionCondition == SetChangeWhileHeld) && whileHeldStatus) setChangeTimer.start(0); else if (setSelectionCondition != SetChangeWhileHeld) setChangeTimer.start(); } else { changeStatesQueue(false); } } else { changeStatesQueue(true); } if (currentRelease == nullptr) { restartAccelParams(true, true, false); lastMouseDistance = 0.0; currentMouseDistance = 0.0; updateStartingMouseDistance = true; if ((slotiter != nullptr) && !slotiter->hasNext()) { // At the end of the list of assignments. qDebug() << "There is end of slotiter. Set currentCycle and previousCycle as null pointers"; currentCycle = nullptr; previousCycle = nullptr; slotiter->toFront(); } else if ((slotiter != nullptr) && slotiter->hasNext() && (currentCycle != nullptr)) { // Cycle at the end of a segment. qDebug() << "There exists next element in slotiter and exists currentCycle. Skip to currentCycle in slotiter " "starting from beginning"; slotiter->toFront(); slotiter->findNext(currentCycle); } else if ((slotiter != nullptr) && slotiter->hasPrevious() && slotiter->hasNext() && (currentCycle == nullptr)) { // Check if there is a cycle action slot after // current slot. Useful after dealing with pause // actions. qDebug() << "There exists next element and previous element in slotiter but doesn't exists currentCycle. From " "current point in slotiter find JoyButtonSlot::JoyCycle as slotMode and assign to currentCycle"; JoyButtonSlot *tempslot = nullptr; bool exit = false; while (slotiter->hasNext() && !exit) { tempslot = slotiter->next(); if (tempslot->getSlotMode() == JoyButtonSlot::JoyCycle) { currentCycle = tempslot; exit = true; } } // Didn't find any cycle. Move iterator // to the front. if (currentCycle == nullptr) { qDebug() << "Didn't find any cycle. Back to start of slotiter"; slotiter->toFront(); previousCycle = nullptr; } } if (currentCycle != nullptr) { qDebug() << "currentCycle exists and previousCycle will be current but current will be null pointer"; previousCycle = currentCycle; currentCycle = nullptr; } else if ((slotiter != nullptr) && slotiter->hasNext() && containsReleaseSlots()) { qDebug() << "Slotiter has next element on the list. In assignments exists JoyButtonSlot::JoyRelease starting " "from current point. CurrentCycle and previousCycle are set null pointers now"; currentCycle = nullptr; previousCycle = nullptr; slotiter->toFront(); } m_currentDistance = nullptr; this->currentKeyPress = nullptr; quitEvent = true; } } void JoyButton::changeStatesQueue(bool currentReleased) { bool tempFinalState = false; if (!isButtonPressedQueue.isEmpty()) { tempFinalState = isButtonPressedQueue.last(); isButtonPressedQueue.clear(); if (currentReleased) { if (tempFinalState || (currentRelease != nullptr)) isButtonPressedQueue.enqueue(tempFinalState); } else { if (tempFinalState) isButtonPressedQueue.enqueue(tempFinalState); } } if (!ignoreSetQueue.isEmpty()) { bool tempFinalIgnoreSetsState = ignoreSetQueue.last(); ignoreSetQueue.clear(); if (currentReleased) { if (tempFinalState || (currentRelease != nullptr)) ignoreSetQueue.enqueue(tempFinalIgnoreSetsState); } else { if (tempFinalState) ignoreSetQueue.enqueue(tempFinalIgnoreSetsState); } } } /** * @brief Get the distance that an element is away from its assigned * dead zone * @return Normalized distance away from dead zone */ double JoyButton::getDistanceFromDeadZone() { return isButtonPressed ? 1.0 : 0.0; } double JoyButton::getAccelerationDistance() { return this->getDistanceFromDeadZone(); } /** * @brief Get the distance factor that should be used for mouse movement * @return Distance factor that should be used for mouse movement */ double JoyButton::getMouseDistanceFromDeadZone() { return this->getDistanceFromDeadZone(); } double JoyButton::getTotalSlotDistance(JoyButtonSlot *slot) { double tempDistance = 0.0; QListIterator iter(*getAssignedSlots()); while (iter.hasNext()) { JoyButtonSlot *currentSlot = iter.next(); int tempcode = currentSlot->getSlotCode(); JoyButtonSlot::JoySlotInputAction mode = currentSlot->getSlotMode(); if (mode == JoyButtonSlot::JoyDistance) { tempDistance += tempcode / 100.0; if (slot == currentSlot) iter.toBack(); } else if (mode == JoyButtonSlot::JoyCycle) // Reset tempDistance { tempDistance = 0.0; } } return tempDistance; } bool JoyButton::containsDistanceSlots() { bool result = false; QListIterator iter(*getAssignedSlots()); while (iter.hasNext()) { JoyButtonSlot *slot = iter.next(); if (slot->getSlotMode() == JoyButtonSlot::JoyDistance) { result = true; iter.toBack(); } } return result; } void JoyButton::clearAssignedSlots(bool signalEmit) { QListIterator iter(assignments); while (iter.hasNext()) { auto *slot = iter.next(); qDebug() << "AssignedSLot mode: " << slot->getSlotMode(); qDebug() << "cleared assigned slot's mode: " << slot->getSlotMode(); qDebug() << "list of mix slots is a null pointer? " << ((slot->getMixSlots() == nullptr) ? "yes" : "no"); if (slot != nullptr) { if (slot->getMixSlots() != nullptr && slot->getMixSlots() != NULL) { slot->cleanMixSlots(); } slot->deleteLater(); slot = nullptr; } } getAssignmentsLocal().clear(); if (signalEmit) emit slotsChanged(); } void JoyButton::removeAssignedSlot(int index) { QWriteLocker tempAssignLocker(&assignmentsLock); int j = 0; qDebug() << "Assigned list slots after joining"; for (auto el : *getAssignedSlots()) { qDebug() << j << ")"; qDebug() << "code: " << el->getSlotCode(); qDebug() << "mode: " << el->getSlotMode(); qDebug() << "string: " << el->getSlotString(); j++; } if ((index >= 0) && (index < getAssignedSlots()->size())) { JoyButtonSlot *slot = getAssignedSlots()->takeAt(index); if (slot->getSlotMode() == JoyButtonSlot::JoyMix) { for (auto minislot : *slot->getMixSlots()) { minislot->deleteLater(); minislot = nullptr; } slot->getMixSlots()->clear(); delete slot->getMixSlots(); slot->assignMixSlotsToNull(); getAssignedSlots()->removeAt(index); } else { slot->deleteLater(); slot = nullptr; } tempAssignLocker.unlock(); buildActiveZoneSummaryString(); emit slotsChanged(); } } void JoyButton::clearSlotsEventReset(bool clearSignalEmit) { assignmentsLock.lockForWrite(); resetSlotsProp(); stopTimers(false); releaseActiveSlots(); clearAssignedSlots(clearSignalEmit); clearQueues(); assignmentsLock.unlock(); buildActiveZoneSummaryString(); DEBUG() << "all current slots and previous slots ale cleared"; } void JoyButton::eventReset() { QWriteLocker tempAssignLocker(&assignmentsLock); resetSlotsProp(); stopTimers(false); clearQueues(); qDebug() << "all current slots and previous slots ale cleared"; releaseActiveSlots(); } void JoyButton::releaseActiveSlots() { if (!getActiveSlots().isEmpty()) { QWriteLocker tempLocker(&activeZoneLock); bool changeRepeatState = false; QListIterator iter(getActiveSlots()); iter.toBack(); while (iter.hasPrevious()) { JoyButtonSlot *slot = iter.previous(); int tempcode = slot->getSlotCode(); int references = 0; JoyButtonSlot::JoySlotInputAction mode = slot->getSlotMode(); if (mode == JoyButtonSlot::JoySlotInputAction::JoyMix) { QListIterator iterMini(*slot->getMixSlots()); iterMini.toBack(); // go through all slots in JoyMix slot while (iterMini.hasPrevious()) { JoyButtonSlot *slotMini = iterMini.previous(); int tempcodeMini = slotMini->getSlotCode(); int referencesMini = 0; JoyButtonSlot::JoySlotInputAction mode = slotMini->getSlotMode(); releaseEachSlot(changeRepeatState, referencesMini, tempcodeMini, mode, slotMini); } if (!slot->getMixSlots()->isEmpty()) { qDeleteAll(*slot->getMixSlots()); slot->getMixSlots()->clear(); delete slot->getMixSlots(); slot->assignMixSlotsToNull(); } } else { releaseEachSlot(changeRepeatState, references, tempcode, mode, slot); } } getActiveSlotsLocal().clear(); currentMouseEvent = nullptr; if (!mouseEventQueue.isEmpty()) mouseEventQueue.clear(); pendingMouseButtons.removeAll(this); currentWheelVerticalEvent = nullptr; currentWheelHorizontalEvent = nullptr; mouseWheelVerticalEventTimer.stop(); mouseWheelHorizontalEventTimer.stop(); if (!mouseWheelVerticalEventQueue.isEmpty()) { mouseWheelVerticalEventQueue.clear(); lastWheelVerticalDistance = getMouseDistanceFromDeadZone(); wheelVerticalTime.restart(); } if (!mouseWheelHorizontalEventQueue.isEmpty()) { mouseWheelHorizontalEventQueue.clear(); lastWheelHorizontalDistance = getMouseDistanceFromDeadZone(); wheelHorizontalTime.restart(); } // Check if mouse remainder should be zero. // Only need to check one list from cursor speeds and spring speeds // since the correspond Y lists will be the same size. if ((pendingMouseButtons.length() == 0) && (cursorXSpeeds.length() == 0) && (springXSpeeds.length() == 0)) { GlobalVariables::JoyButton::cursorRemainderX = 0; GlobalVariables::JoyButton::cursorRemainderY = 0; } } } void JoyButton::releaseEachSlot(bool &changeRepeatState, int &references, int tempcode, JoyButtonSlot::JoySlotInputAction mode, JoyButtonSlot *slot) { if (mode == JoyButtonSlot::JoyKeyboard) { countActiveSlots(tempcode, references, slot, GlobalVariables::JoyButton::activeKeys, changeRepeatState, true); if ((lastActiveKey == slot) && (references <= 0)) lastActiveKey = nullptr; } else if (mode == JoyButtonSlot::JoyMouseButton) { if ((tempcode != static_cast(JoyButtonSlot::MouseWheelUp)) && (tempcode != static_cast(JoyButtonSlot::MouseWheelDown)) && (tempcode != static_cast(JoyButtonSlot::MouseWheelLeft)) && (tempcode != static_cast(JoyButtonSlot::MouseWheelRight))) { countActiveSlots(tempcode, references, slot, GlobalVariables::JoyButton::activeMouseButtons, changeRepeatState); } else if ((tempcode == static_cast(JoyButtonSlot::MouseWheelUp)) || (tempcode == static_cast(JoyButtonSlot::MouseWheelDown))) { mouseWheelVerticalEventQueue.removeAll(slot); } else if ((tempcode == static_cast(JoyButtonSlot::MouseWheelLeft)) || (tempcode == static_cast(JoyButtonSlot::MouseWheelRight))) { mouseWheelHorizontalEventQueue.removeAll(slot); } slot->setDistance(0.0); slot->getMouseInterval()->restart(); } else if (mode == JoyButtonSlot::JoyMouseMovement) { JoyMouseMovementMode mousemode = getMouseMode(); if (mousemode == MouseCursor) { QList indexesToRemove; releaseMoveSlots(cursorXSpeeds, slot, indexesToRemove); releaseMoveSlots(cursorYSpeeds, slot, indexesToRemove); slot->getEasingTime()->restart(); slot->setEasingStatus(false); } else if (mousemode == JoyButton::MouseSpring) { double mouse1 = (tempcode == static_cast(JoyButtonSlot::MouseLeft) || tempcode == static_cast(JoyButtonSlot::MouseRight)) ? 0.0 : -2.0; double mouse2 = (tempcode == static_cast(JoyButtonSlot::MouseUp) || tempcode == static_cast(JoyButtonSlot::MouseDown)) ? 0.0 : -2.0; double springDeadCircleX = 0.0; double springDeadCircleY = 0.0; checkSpringDeadCircle(tempcode, springDeadCircleX, JoyButtonSlot::MouseLeft, JoyButtonSlot::MouseRight); checkSpringDeadCircle(tempcode, springDeadCircleY, JoyButtonSlot::MouseUp, JoyButtonSlot::MouseDown); updateMouseProperties(mouse1, springDeadCircleX, springWidth, springHeight, relativeSpring, GlobalVariables::JoyButton::springModeScreen, springXSpeeds, 'n', -2.0, springDeadCircleY); updateMouseProperties(-2.0, springDeadCircleX, springWidth, springHeight, relativeSpring, GlobalVariables::JoyButton::springModeScreen, springYSpeeds, 'n', mouse2, springDeadCircleY); } mouseEventQueue.removeAll(slot); slot->setDistance(0.0); slot->getMouseInterval()->restart(); } else if (mode == JoyButtonSlot::JoyMouseSpeedMod) { int queueLength = mouseSpeedModList.length(); if (!mouseSpeedModList.isEmpty()) { mouseSpeedModList.removeAll(slot); queueLength -= 1; } if (queueLength <= 0) GlobalVariables::JoyButton::mouseSpeedModifier = GlobalVariables::JoyButton::DEFAULTMOUSESPEEDMOD; } else if (mode == JoyButtonSlot::JoySetChange) { currentSetChangeSlot = slot; slotSetChangeTimer.start(); } } void JoyButton::countActiveSlots(int tempcode, int &references, JoyButtonSlot *slot, QHash &activeSlotsHash, bool &changeRepeatState, bool activeSlotHashWindows) { changeRepeatState = false; references = activeSlotsHash.value(tempcode, 1) - 1; if (references <= 0) { sendevent(slot, false); activeSlotsHash.remove(tempcode); } else { activeSlotsHash.insert(tempcode, references); } } void JoyButton::setSpringDeadCircle(double &springDeadCircle, int mouseDirection) { if (getCurrentSpringDeadCircle() > getLastMouseDistanceFromDeadZone()) springDeadCircle = (mouseDirection == JoyButtonSlot::MouseLeft || mouseDirection == JoyButtonSlot::MouseUp) ? -getLastMouseDistanceFromDeadZone() : getLastMouseDistanceFromDeadZone(); else springDeadCircle = (mouseDirection == JoyButtonSlot::MouseLeft || mouseDirection == JoyButtonSlot::MouseUp) ? -getCurrentSpringDeadCircle() : getCurrentSpringDeadCircle(); } void JoyButton::checkSpringDeadCircle(int tempcode, double &springDeadCircle, int mouseSlot1, int mouseSlot2) { if (getSpringDeadCircleMultiplier() > 0) { if (tempcode == mouseSlot1) { setSpringDeadCircle(springDeadCircle, mouseSlot1); } else if (tempcode == mouseSlot2) { setSpringDeadCircle(springDeadCircle, mouseSlot2); } } } void JoyButton::releaseMoveSlots(QList &cursorSpeeds, JoyButtonSlot *slot, QList &indexesToRemove) { QListIterator iter(cursorSpeeds); int i = cursorSpeeds.length(); while (iter.hasNext()) { mouseCursorInfo info = iter.next(); if (info.slot == slot) indexesToRemove.append(i); i++; } QListIterator removeIter(indexesToRemove); while (removeIter.hasPrevious()) { int index = removeIter.previous(); cursorSpeeds.removeAt(index); } indexesToRemove.clear(); } bool JoyButton::containsReleaseSlots() { bool result = false; QListIterator iter(*getAssignedSlots()); while (iter.hasNext()) { if (iter.next()->getSlotMode() == JoyButtonSlot::JoyRelease) { result = true; iter.toBack(); } } return result; } bool JoyButton::containsJoyMixSlot() { bool result = false; QListIterator iter(*getAssignedSlots()); while (iter.hasNext()) { if (iter.next()->getSlotMode() == JoyButtonSlot::JoyMix) { result = true; iter.toBack(); } } return result; } void JoyButton::releaseSlotEvent() { JoyButtonSlot *temp = nullptr; int timeElapsed = buttonHeldRelease.elapsed(); if (containsReleaseSlots()) { QListIterator iter(*getAssignedSlots()); if (previousCycle != nullptr) iter.findNext(previousCycle); int tempElapsed = 0; while (iter.hasNext()) { JoyButtonSlot *currentSlot = iter.next(); int tempcode = currentSlot->getSlotCode(); JoyButtonSlot::JoySlotInputAction mode = currentSlot->getSlotMode(); if (mode == JoyButtonSlot::JoyRelease) { tempElapsed += tempcode; if (tempElapsed <= timeElapsed) temp = currentSlot; else iter.toBack(); } else if (mode == JoyButtonSlot::JoyCycle) { tempElapsed = 0; iter.toBack(); } } if ((temp != nullptr) && (slotiter != nullptr)) { slotiter->toFront(); slotiter->findNext(temp); currentRelease = temp; activateSlots(); if (!keyPressTimer.isActive() && !pauseWaitTimer.isActive()) { releaseActiveSlots(); currentRelease = nullptr; } // Stop hold timer here to be sure that // a hold timer that could be activated // during a release event is stopped. holdTimer.stop(); currentHold = nullptr; } } } void JoyButton::findJoySlotsEnd(QListIterator *slotiter) { if (slotiter != nullptr) { bool found = false; while (!found && slotiter->hasNext()) { qDebug() << "slotiter has next element"; JoyButtonSlot::JoySlotInputAction mode = slotiter->next()->getSlotMode(); switch (mode) { case JoyButtonSlot::JoyRelease: case JoyButtonSlot::JoyCycle: case JoyButtonSlot::JoyHold: found = true; break; default: break; } } if (found && slotiter->hasPrevious()) slotiter->previous(); } } void JoyButton::setVDPad(VDPad *vdpad) { joyEvent(false, true); m_vdpad = vdpad; emit propertyUpdated(); } bool JoyButton::isPartVDPad() { return (m_vdpad != nullptr); } VDPad *JoyButton::getVDPad() { return m_vdpad; } void JoyButton::removeVDPad() { m_vdpad = nullptr; emit propertyUpdated(); } /** * @brief Check if button properties are at their default values * @return Status of possible property edits */ bool JoyButton::isDefault() { bool value = true; value = value && (m_toggle == GlobalVariables::JoyButton::DEFAULTTOGGLE); value = value && (turboInterval == GlobalVariables::JoyButton::DEFAULTTURBOINTERVAL); value = value && (currentTurboMode == NormalTurbo); value = value && (m_useTurbo == GlobalVariables::JoyButton::DEFAULTUSETURBO); value = value && (mouseSpeedX == GlobalVariables::JoyButton::DEFAULTMOUSESPEEDX); value = value && (mouseSpeedY == GlobalVariables::JoyButton::DEFAULTMOUSESPEEDY); value = value && (setSelection == GlobalVariables::JoyButton::DEFAULTSETSELECTION); value = value && (setSelectionCondition == DEFAULTSETCONDITION); value = value && (getAssignedSlots()->isEmpty()); value = value && (mouseMode == DEFAULTMOUSEMODE); value = value && (mouseCurve == getDefaultMouseCurve()); value = value && (springWidth == GlobalVariables::JoyButton::DEFAULTSPRINGWIDTH); value = value && (springHeight == GlobalVariables::JoyButton::DEFAULTSPRINGHEIGHT); value = value && qFuzzyCompare(sensitivity, GlobalVariables::JoyButton::DEFAULTSENSITIVITY); value = value && (actionName.isEmpty()); value = value && (wheelSpeedX == GlobalVariables::JoyButton::DEFAULTWHEELX); value = value && (wheelSpeedY == GlobalVariables::JoyButton::DEFAULTWHEELY); value = value && (cycleResetActive == GlobalVariables::JoyButton::DEFAULTCYCLERESETACTIVE); value = value && (cycleResetInterval == GlobalVariables::JoyButton::DEFAULTCYCLERESET); value = value && (relativeSpring == GlobalVariables::JoyButton::DEFAULTRELATIVESPRING); value = value && qFuzzyCompare(m_easingDuration, GlobalVariables::JoyButton::DEFAULTEASINGDURATION); value = value && !extraAccelerationEnabled; value = value && qFuzzyCompare(extraAccelerationMultiplier, GlobalVariables::JoyButton::DEFAULTEXTRACCELVALUE); value = value && qFuzzyCompare(minMouseDistanceAccelThreshold, GlobalVariables::JoyButton::DEFAULTMINACCELTHRESHOLD); value = value && qFuzzyCompare(maxMouseDistanceAccelThreshold, GlobalVariables::JoyButton::DEFAULTMAXACCELTHRESHOLD); value = value && qFuzzyCompare(startAccelMultiplier, GlobalVariables::JoyButton::DEFAULTSTARTACCELMULTIPLIER); value = value && qFuzzyCompare(accelDuration, GlobalVariables::JoyButton::DEFAULTACCELEASINGDURATION); value = value && (springDeadCircleMultiplier == GlobalVariables::JoyButton::DEFAULTSPRINGRELEASERADIUS); value = value && (extraAccelCurve == DEFAULTEXTRAACCELCURVE); return value; } /** * @brief Returns the default mouse curve for this JoyButton type. * Can be overwritten by subclasses. * @returns Default mouse curve */ JoyButton::JoyMouseCurve JoyButton::getDefaultMouseCurve() const { return DEFAULTMOUSECURVE; } void JoyButton::setIgnoreEventState(bool ignore) { ignoreEvents = ignore; } bool JoyButton::getIgnoreEventState() { return ignoreEvents; } void JoyButton::setMouseMode(JoyMouseMovementMode mousemode) { this->mouseMode = mousemode; emit propertyUpdated(); } JoyButton::JoyMouseMovementMode JoyButton::getMouseMode() { return mouseMode; } void JoyButton::setMouseCurve(JoyMouseCurve selectedCurve) { mouseCurve = selectedCurve; emit propertyUpdated(); } JoyButton::JoyMouseCurve JoyButton::getMouseCurve() { return mouseCurve; } void JoyButton::setSpringWidth(int value) { if (value >= 0) { springWidth = value; emit propertyUpdated(); } } int JoyButton::getSpringWidth() { return springWidth; } void JoyButton::setSpringHeight(int value) { if (springHeight >= 0) { springHeight = value; emit propertyUpdated(); } } int JoyButton::getSpringHeight() { return springHeight; } void JoyButton::setSensitivity(double value) { if ((value >= 0.001) && (value <= 1000)) { sensitivity = value; emit propertyUpdated(); } } double JoyButton::getSensitivity() { return sensitivity; } bool JoyButton::getWhileHeldStatus() { return whileHeldStatus; } void JoyButton::setWhileHeldStatus(bool status) { whileHeldStatus = status; } void JoyButton::setActionName(QString tempName) { if ((tempName.length() <= 50) && (tempName != actionName)) { actionName = tempName; emit actionNameChanged(); emit propertyUpdated(); } } QString JoyButton::getActionName() { return actionName; } void JoyButton::setButtonName(QString tempName) { if ((tempName.length() <= 20) && (tempName != buttonName)) { buttonName = tempName; emit buttonNameChanged(); emit propertyUpdated(); } } QString JoyButton::getButtonName() { return buttonName; } void JoyButton::setWheelSpeed(int speed, QChar ax) { if ((speed >= 1) && (speed <= 100)) { if (ax == 'X') wheelSpeedX = speed; else if (ax == 'Y') wheelSpeedY = speed; emit propertyUpdated(); } } int JoyButton::getWheelSpeedX() { return wheelSpeedX; } int JoyButton::getWheelSpeedY() { return wheelSpeedY; } void JoyButton::setDefaultButtonName(QString tempname) { defaultButtonName = tempname; } QString JoyButton::getDefaultButtonName() { return defaultButtonName; } /** * @brief Take cursor mouse information provided by all buttons and * send a cursor mode mouse event to the display server. */ void JoyButton::moveMouseCursor(int &movedX, int &movedY, int &movedElapsed, QList *mouseHistoryX, QList *mouseHistoryY, QElapsedTimer *testOldMouseTime, QTimer *staticMouseEventTimer, int mouseRefreshRate, int mouseHistorySize, QList *cursorXSpeeds, QList *cursorYSpeeds, double &cursorRemainderX, double &cursorRemainderY, double weightModifier, int idleMouseRefrRate, QList *pendingMouseButtons) { movedX = 0; movedY = 0; int elapsedTime = testOldMouseTime->elapsed(); movedElapsed = elapsedTime; if (staticMouseEventTimer->interval() < mouseRefreshRate) movedElapsed = mouseRefreshRate + (elapsedTime - staticMouseEventTimer->interval()); if (mouseHistoryX->size() >= mouseHistorySize) mouseHistoryX->removeLast(); if (mouseHistoryY->size() >= mouseHistorySize) mouseHistoryY->removeLast(); /* * Combine all mouse events to find the distance to move the mouse * along the X and Y axis. If necessary, perform mouse smoothing. * The mouse smoothing technique used is an interpretation of the method * outlined at http://flipcode.net/archives/Smooth_Mouse_Filtering.shtml. */ if ((cursorXSpeeds->length() == cursorYSpeeds->length()) && (cursorXSpeeds->length() > 0)) { int queueLength = cursorXSpeeds->length(); double finalx = 0.0; double finaly = 0.0; for (int i = 0; i < queueLength; i++) { mouseCursorInfo infoX = cursorXSpeeds->takeFirst(); mouseCursorInfo infoY = cursorYSpeeds->takeFirst(); distanceForMovingAx(finalx, infoX); distanceForMovingAx(finaly, infoY); infoX.slot->getMouseInterval()->restart(); infoY.slot->getMouseInterval()->restart(); } // Only apply remainder if both current displacement and remainder // follow the same direction. if ((cursorRemainderX >= 0) == (finalx >= 0)) finalx += cursorRemainderX; // Cap maximum relative mouse movement. if (abs(finalx) > 127) finalx = (finalx < 0) ? -127 : 127; mouseHistoryX->prepend(finalx); // Only apply remainder if both current displacement and remainder // follow the same direction. if ((cursorRemainderY >= 0) == (finaly >= 0)) finaly += cursorRemainderY; // Cap maximum relative mouse movement. if (abs(finaly) > 127) finaly = (finaly < 0) ? -127 : 127; mouseHistoryY->prepend(finaly); cursorRemainderX = 0; cursorRemainderY = 0; double adjustedX = 0; double adjustedY = 0; adjustAxForCursor(mouseHistoryX, adjustedX, cursorRemainderX, weightModifier); adjustAxForCursor(mouseHistoryY, adjustedY, cursorRemainderY, weightModifier); // This check is more of a precaution than anything. No need to cause // a sync to happen when not needed. if (!qFuzzyIsNull(adjustedX) || !qFuzzyIsNull(adjustedY)) sendevent(adjustedX, adjustedY); movedX = adjustedX; movedY = adjustedY; } else { mouseHistoryX->prepend(0); mouseHistoryY->prepend(0); } // Check if mouse event timer should use idle time. if (pendingMouseButtons->length() == 0) { if (staticMouseEventTimer->interval() != idleMouseRefrRate) { staticMouseEventTimer->start(idleMouseRefrRate); // Clear current mouse history mouseHistoryX->clear(); mouseHistoryY->clear(); // Fill history with zeroes. for (int i = 0; i < mouseHistorySize; i++) { mouseHistoryX->append(0); mouseHistoryY->append(0); } } cursorRemainderX = 0; cursorRemainderY = 0; } else { if (staticMouseEventTimer->interval() != mouseRefreshRate) staticMouseEventTimer->start(mouseRefreshRate); // Restore intended QTimer interval. } cursorXSpeeds->clear(); cursorYSpeeds->clear(); } /** * @brief Combines mouse movement distances from multiple mouse mappings. * @param[in,out] finalAx Combined mouse distance from previous iteration. Updated by this function. * @param[in] infoAx Next mouse event to join into finalAx. */ void JoyButton::distanceForMovingAx(double &finalAx, mouseCursorInfo infoAx) { if (!qFuzzyIsNull(infoAx.code)) finalAx += infoAx.code; } void JoyButton::adjustAxForCursor(QList *mouseHistoryList, double &adjustedAx, double &cursorRemainder, double weightModifier) { double currentWeight = 1.0; double finalWeight = 0.0; QListIterator mouseHist(*mouseHistoryList); while (mouseHist.hasNext()) { adjustedAx += mouseHist.next() * currentWeight; finalWeight += currentWeight; currentWeight *= weightModifier; } if (fabs(adjustedAx) > 0) { adjustedAx = adjustedAx / finalWeight; double oldAx = adjustedAx; if (adjustedAx > 0) adjustedAx = floor(adjustedAx); else adjustedAx = ceil(adjustedAx); cursorRemainder = oldAx - adjustedAx; } } /** * @brief Take spring mouse information provided by all buttons and * send a spring mode mouse event to the display server. */ void JoyButton::moveSpringMouse(int &movedX, int &movedY, bool &hasMoved, int springModeScreen, QList *springXSpeeds, QList *springYSpeeds, QList *pendingMouseButtons, int mouseRefreshRate, int idleMouseRefrRate, QTimer *staticMouseEventTimer) { PadderCommon::springModeInfo fullSpring = {-2.0, -2.0, 0, 0, false, springModeScreen, 0.0, 0.0}; PadderCommon::springModeInfo relativeSpring = {-2.0, -2.0, 0, 0, false, springModeScreen, 0.0, 0.0}; int realMouseX = movedX = 0; int realMouseY = movedY = 0; hasMoved = false; if ((springXSpeeds->length() == springYSpeeds->length()) && (springXSpeeds->length() > 0)) { bool complete = false; for (int i = (springXSpeeds->length() - 1); (i >= 0) && !complete; i--) { double tempSpringDeadX = 0.0; double tempSpringDeadY = 0.0; PadderCommon::springModeInfo infoX; PadderCommon::springModeInfo infoY; infoX = springXSpeeds->takeLast(); infoY = springYSpeeds->takeLast(); double tempx = infoX.displacementX; double tempy = infoY.displacementY; tempSpringDeadX = infoX.springDeadX; tempSpringDeadY = infoY.springDeadY; if (infoX.relative) { if (qFuzzyCompare(relativeSpring.displacementX, -2.0)) relativeSpring.displacementX = tempx; relativeSpring.relative = true; // Use largest found width for spring // mode dimensions. relativeSpring.width = qMax(infoX.width, relativeSpring.width); } else { if (qFuzzyCompare(fullSpring.displacementX, -2.0)) fullSpring.displacementX = tempx; if (fullSpring.springDeadX == 0.0) fullSpring.springDeadX = tempSpringDeadX; // Use largest found width for spring // mode dimensions. fullSpring.width = qMax(infoX.width, fullSpring.width); } if (infoY.relative) { if (qFuzzyCompare(relativeSpring.displacementY, -2.0)) relativeSpring.displacementY = tempy; relativeSpring.relative = true; // Use largest found height for spring // mode dimensions. relativeSpring.height = qMax(infoX.height, relativeSpring.height); } else { if (qFuzzyCompare(fullSpring.displacementY, -2.0)) fullSpring.displacementY = tempy; if (fullSpring.springDeadY == 0.0) fullSpring.springDeadY = tempSpringDeadY; // Use largest found height for spring // mode dimensions. fullSpring.height = qMax(infoX.height, fullSpring.height); } if ((!qFuzzyCompare(relativeSpring.displacementX, -2.0) && !qFuzzyCompare(relativeSpring.displacementY, -2.0)) && (!qFuzzyCompare(fullSpring.displacementX, -2.0) && !qFuzzyCompare(fullSpring.displacementY, -2.0))) { complete = true; } else if (((relativeSpring.springDeadX != 0.0) && (relativeSpring.springDeadY != 0.0)) && ((fullSpring.springDeadX != 0.0) && (fullSpring.springDeadY != 0.0))) { complete = true; } } fullSpring.screen = springModeScreen; relativeSpring.screen = springModeScreen; if (relativeSpring.relative) { sendSpringEvent(&fullSpring, &relativeSpring, &realMouseX, &realMouseY); } else { if (!hasFutureSpringEvents(JoyButton::getPendingMouseButtons())) { if (fullSpring.springDeadX != 0.0) fullSpring.displacementX = fullSpring.springDeadX; if (fullSpring.springDeadY != 0.0) fullSpring.displacementY = fullSpring.springDeadY; sendSpringEvent(&fullSpring, nullptr, &realMouseX, &realMouseY); } else { sendSpringEvent(&fullSpring, nullptr, &realMouseX, &realMouseY); } } movedX = realMouseX; movedY = realMouseY; hasMoved = true; } // Check if mouse event timer should use idle time. if (pendingMouseButtons->length() == 0) { staticMouseEventTimer->start(idleMouseRefrRate); } else { if (staticMouseEventTimer->interval() != mouseRefreshRate) // Restore intended QTimer interval. staticMouseEventTimer->start(mouseRefreshRate); } springXSpeeds->clear(); springYSpeeds->clear(); } void JoyButton::keyPressEvent() { if (keyPressTimer.isActive() && (keyPressHold.elapsed() >= getPreferredKeyPressTime())) { currentKeyPress = nullptr; keyPressTimer.stop(); keyPressHold.restart(); releaseActiveSlots(); createDeskTimer.stop(); if (currentRelease != nullptr) { releaseDeskTimer.stop(); createDeskEvent(); waitForReleaseDeskEvent(); } else { createDeskEvent(); } } else { createDeskTimer.stop(); startTimerOverrun(getPreferredKeyPressTime(), &keyPressHold, &keyPressTimer, true); } } /** * @brief TODO: CHECK IF METHOD WOULD BE USEFUL. CURRENTLY NOT USED. * @return Result */ bool JoyButton::checkForDelaySequence() { bool result = false; QListIterator tempiter(*getAssignedSlots()); // Move iterator to start of cycle. if (previousCycle != nullptr) tempiter.findNext(previousCycle); while (tempiter.hasNext()) { JoyButtonSlot *slot = tempiter.next(); if ((slot->getSlotMode() == JoyButtonSlot::JoyPause) || (slot->getSlotMode() == JoyButtonSlot::JoyRelease)) { result = true; tempiter.toBack(); } else if (slot->getSlotMode() == JoyButtonSlot::JoyCycle) { result = false; tempiter.toBack(); } } return result; } SetJoystick *JoyButton::getParentSet() { return m_parentSet; } void JoyButton::checkForPressedSetChange() { if (!isButtonPressedQueue.isEmpty() && !whileHeldStatus) { bool tempButtonPressed = isButtonPressedQueue.last(); bool tempFinalIgnoreSetsState = ignoreSetQueue.last(); if (tempButtonPressed && !tempFinalIgnoreSetsState && (setSelectionCondition == SetChangeWhileHeld) && (currentRelease == nullptr)) { setChangeTimer.start(0); quitEvent = true; } } } /** * @brief Obtain the appropriate key press time for the current event. * Order of preference: active key press time slot value -> * profile value -> program default value. * @return Appropriate key press time for current event. */ int JoyButton::getPreferredKeyPressTime() { if ((currentKeyPress != nullptr) && (currentKeyPress->getSlotCode() > 0)) { return currentKeyPress->getSlotCode(); } else if ((m_parentSet != nullptr) && (m_parentSet->getInputDevice()->getDeviceKeyPressTime() > 0)) { return m_parentSet->getInputDevice()->getDeviceKeyPressTime(); } return GlobalVariables::InputDevice::NUMBER_JOYSETS; } void JoyButton::setCycleResetTime(int interval) { if (interval >= GlobalVariables::JoyButton::MINCYCLERESETTIME) cycleResetInterval = qBound(GlobalVariables::JoyButton::MINCYCLERESETTIME, interval, GlobalVariables::JoyButton::MAXCYCLERESETTIME); else cycleResetActive = false; emit propertyUpdated(); } int JoyButton::getCycleResetTime() { return cycleResetInterval; } void JoyButton::setCycleResetStatus(bool enabled) { cycleResetActive = enabled; emit propertyUpdated(); } bool JoyButton::isCycleResetActive() { return cycleResetActive; } void JoyButton::establishPropertyUpdatedConnections() { Q_ASSERT(!m_parentSet.isNull()); connect(this, &JoyButton::slotsChanged, m_parentSet->getInputDevice(), &InputDevice::profileEdited); connect(this, &JoyButton::propertyUpdated, m_parentSet->getInputDevice(), &InputDevice::profileEdited); } void JoyButton::disconnectPropertyUpdatedConnections() { disconnect(this, &JoyButton::slotsChanged, nullptr, nullptr); if (!m_parentSet.isNull()) disconnect(this, &JoyButton::propertyUpdated, m_parentSet->getInputDevice(), &InputDevice::profileEdited); } /** * @brief Change initial settings used for mouse event timer being used by * the application. */ void JoyButton::establishMouseTimerConnections() { if (staticMouseEventTimer.timerType() != Qt::PreciseTimer) staticMouseEventTimer.setTimerType(Qt::PreciseTimer); // Only one connection will be made for each. connect(&staticMouseEventTimer, &QTimer::timeout, &mouseHelper, &JoyButtonMouseHelper::mouseEvent, Qt::UniqueConnection); if (staticMouseEventTimer.interval() != GlobalVariables::JoyButton::IDLEMOUSEREFRESHRATE) staticMouseEventTimer.setInterval(GlobalVariables::JoyButton::IDLEMOUSEREFRESHRATE); } void JoyButton::setSpringRelativeStatus(bool value) { if (value != relativeSpring) { if (value) setSpringDeadCircleMultiplier(0); relativeSpring = value; emit propertyUpdated(); } } bool JoyButton::isRelativeSpring() { return relativeSpring; } /** * @brief Copy assignments and properties from one button to another. * Used for set copying. * @param Button instance that should be modified. */ void JoyButton::copyAssignments(JoyButton *destButton) { destButton->eventReset(); destButton->assignmentsLock.lockForWrite(); destButton->getAssignmentsLocal().clear(); destButton->assignmentsLock.unlock(); assignmentsLock.lockForWrite(); QListIterator iter(*getAssignedSlots()); while (iter.hasNext()) { JoyButtonSlot *slot = iter.next(); JoyButtonSlot *newslot = new JoyButtonSlot(slot, destButton); destButton->insertAssignedSlot(newslot, false); } assignmentsLock.unlock(); destButton->m_toggle = m_toggle; destButton->turboInterval = turboInterval; destButton->m_useTurbo = m_useTurbo; destButton->mouseSpeedX = mouseSpeedX; destButton->mouseSpeedY = mouseSpeedY; destButton->wheelSpeedX = wheelSpeedX; destButton->wheelSpeedY = wheelSpeedY; destButton->mouseMode = mouseMode; destButton->mouseCurve = mouseCurve; destButton->springWidth = springWidth; destButton->springHeight = springHeight; destButton->sensitivity = sensitivity; destButton->buttonName = buttonName; destButton->actionName = actionName; destButton->cycleResetActive = cycleResetActive; destButton->cycleResetInterval = cycleResetInterval; destButton->relativeSpring = relativeSpring; destButton->currentTurboMode = currentTurboMode; destButton->m_easingDuration = m_easingDuration; destButton->extraAccelerationEnabled = extraAccelerationEnabled; destButton->extraAccelerationMultiplier = extraAccelerationMultiplier; destButton->minMouseDistanceAccelThreshold = minMouseDistanceAccelThreshold; destButton->maxMouseDistanceAccelThreshold = maxMouseDistanceAccelThreshold; destButton->startAccelMultiplier = startAccelMultiplier; destButton->springDeadCircleMultiplier = springDeadCircleMultiplier; destButton->extraAccelCurve = extraAccelCurve; destButton->buildActiveZoneSummaryString(); if (!destButton->isDefault()) emit propertyUpdated(); } /** * @brief Set the turbo mode that the button should use * @param Mode that should be used */ void JoyButton::setTurboMode(TurboMode mode) { currentTurboMode = mode; } /** * @brief Get currently assigned turbo mode * @return Currently assigned turbo mode */ JoyButton::TurboMode JoyButton::getTurboMode() { return currentTurboMode; } /** * @brief Check if button should be considered a part of a real controller * axis. Needed for some dialogs so the program won't have to resort to * type checking. * @return Status of being part of a real controller axis */ bool JoyButton::isPartRealAxis() { return false; } /** * @brief Calculate maximum mouse speed when using a given mouse curve. * @param Mouse curve * @param Mouse speed value * @return Final mouse speed */ int JoyButton::calculateFinalMouseSpeed(JoyMouseCurve curve, int value, const float joyspeed) { int result = joyspeed * value; switch (curve) { case QuadraticExtremeCurve: case EasingQuadraticCurve: case EasingCubicCurve: { result *= 1.5; break; } default: { break; } } return result; } void JoyButton::setEasingDuration(double value) { if ((value >= GlobalVariables::JoyButton::MINIMUMEASINGDURATION) && (value <= GlobalVariables::JoyButton::MAXIMUMEASINGDURATION) && (!qFuzzyCompare(value, m_easingDuration))) { m_easingDuration = value; emit propertyUpdated(); } } double JoyButton::getEasingDuration() { return m_easingDuration; } JoyButtonMouseHelper *JoyButton::getMouseHelper() { return &mouseHelper; } /** * @brief Get the list of buttons that have a pending mouse movement event. * @return QList* */ QList *JoyButton::getPendingMouseButtons() { return &pendingMouseButtons; } QList *JoyButton::getCursorXSpeeds() { return &cursorXSpeeds; } QList *JoyButton::getCursorYSpeeds() { return &cursorYSpeeds; } QList *JoyButton::getSpringXSpeeds() { return &springXSpeeds; } QList *JoyButton::getSpringYSpeeds() { return &springYSpeeds; } QTimer *JoyButton::getStaticMouseEventTimer() { return &staticMouseEventTimer; } QElapsedTimer *JoyButton::getTestOldMouseTime() { return &testOldMouseTime; } bool JoyButton::hasCursorEvents(QList *cursorXSpeedsList, QList *cursorYSpeedsList) { // qInstallMessageHandler(MessageHandler::myMessageOutput); return (cursorXSpeedsList->length() != 0) || (cursorYSpeedsList->length() != 0); } bool JoyButton::hasSpringEvents(QList *springXSpeedsList, QList *springYSpeedsList) { return (springXSpeedsList->length() != 0) || (springYSpeedsList->length() != 0); } /** * @brief Set the weight modifier to use for mouse smoothing. * @param Weight modifier in the range of 0.0 - 1.0. */ void JoyButton::setWeightModifier(double modifier, double maxWeightModifier, double &weightModifier) { if ((modifier >= 0.0) && (modifier <= maxWeightModifier)) weightModifier = modifier; } /** * @brief Set mouse history buffer size used for mouse smoothing. * @param Mouse history buffer size */ void JoyButton::setMouseHistorySize(int size, int maxMouseHistSize, int &mouseHistSize, QList *mouseHistoryX, QList *mouseHistoryY) { if ((size >= 1) && (size <= maxMouseHistSize)) { mouseHistoryX->clear(); mouseHistoryY->clear(); mouseHistSize = size; } } /** * @brief Set the mouse refresh rate when a mouse slot is active. * @param Refresh rate in ms. */ void JoyButton::setMouseRefreshRate(int refresh, int &mouseRefreshRate, int idleMouseRefrRate, JoyButtonMouseHelper *mouseHelper, QList *mouseHistoryX, QList *mouseHistoryY, QElapsedTimer *testOldMouseTime, QTimer *staticMouseEventTimer) { if ((refresh >= 1) && (refresh <= 16)) { mouseRefreshRate = refresh; if (staticMouseEventTimer->isActive()) { testOldMouseTime->restart(); if (staticMouseEventTimer->interval() != idleMouseRefrRate && staticMouseEventTimer->interval() != 0) { QMetaObject::invokeMethod(staticMouseEventTimer, "start", Q_ARG(int, mouseRefreshRate)); } else { // Restart QTimer to keep QTimer in line with QTime QMetaObject::invokeMethod(staticMouseEventTimer, "start", Q_ARG(int, idleMouseRefrRate)); } // Clear current mouse history mouseHistoryX->clear(); mouseHistoryY->clear(); } else { staticMouseEventTimer->setInterval(idleMouseRefrRate); } mouseHelper->carryMouseRefreshRateUpdate(mouseRefreshRate); } } /** * @brief Set the gamepad poll rate to be used in the application. * @param Poll rate in ms. */ void JoyButton::setGamepadRefreshRate(int refresh, int &gamepadRefreshRate, JoyButtonMouseHelper *mouseHelper) { if ((refresh >= 1) && (refresh <= 16)) { gamepadRefreshRate = refresh; mouseHelper->carryGamePollRateUpdate(gamepadRefreshRate); } } /** * @brief Check if turbo should be disabled for a slot * @param JoyButtonSlot to check */ void JoyButton::checkTurboCondition(JoyButtonSlot *slot) { JoyButtonSlot::JoySlotInputAction mode = slot->getSlotMode(); switch (mode) { case JoyButtonSlot::JoyPause: case JoyButtonSlot::JoyHold: case JoyButtonSlot::JoyDistance: case JoyButtonSlot::JoyRelease: case JoyButtonSlot::JoyLoadProfile: case JoyButtonSlot::JoySetChange: { setUseTurbo(false); break; } default: { break; } } } void JoyButton::resetProperties() { qDebug() << "all current slots and previous slots ale cleared"; resetAllProperties(); } void JoyButton::resetAllProperties() { resetSlotsProp(true); actionName.clear(); m_toggle = GlobalVariables::JoyButton::DEFAULTTOGGLE; turboInterval = GlobalVariables::JoyButton::DEFAULTTURBOINTERVAL; currentTurboMode = NormalTurbo; m_useTurbo = GlobalVariables::JoyButton::DEFAULTUSETURBO; isDown = false; toggleActiveState = false; m_useTurbo = false; mouseSpeedX = GlobalVariables::JoyButton::DEFAULTMOUSESPEEDX; mouseSpeedY = GlobalVariables::JoyButton::DEFAULTMOUSESPEEDY; wheelSpeedX = GlobalVariables::JoyButton::DEFAULTWHEELX; wheelSpeedY = GlobalVariables::JoyButton::DEFAULTWHEELY; mouseMode = DEFAULTMOUSEMODE; mouseCurve = getDefaultMouseCurve(); springWidth = GlobalVariables::JoyButton::DEFAULTSPRINGWIDTH; springHeight = GlobalVariables::JoyButton::DEFAULTSPRINGHEIGHT; sensitivity = GlobalVariables::JoyButton::DEFAULTSENSITIVITY; setSelection = GlobalVariables::JoyButton::DEFAULTSETSELECTION; setSelectionCondition = DEFAULTSETCONDITION; m_ignoresets = false; ignoreEvents = false; whileHeldStatus = false; buttonName.clear(); actionName.clear(); cycleResetActive = GlobalVariables::JoyButton::DEFAULTCYCLERESETACTIVE; cycleResetInterval = GlobalVariables::JoyButton::DEFAULTCYCLERESET; relativeSpring = GlobalVariables::JoyButton::DEFAULTRELATIVESPRING; lastDistance = 0.0; lastMouseDistance = 0.0; currentMouseDistance = 0.0; updateMouseParams(false, false, 0.0); restartAccelParams(false, false, true); lastWheelVerticalDistance = 0.0; lastWheelHorizontalDistance = 0.0; tempTurboInterval = 0; currentTurboMode = DEFAULTTURBOMODE; m_easingDuration = GlobalVariables::JoyButton::DEFAULTEASINGDURATION; springDeadCircleMultiplier = GlobalVariables::JoyButton::DEFAULTSPRINGRELEASERADIUS; updatePendingParams(false, false, false); lockForWritedString(activeZoneString, tr("[NO KEY]")); } bool JoyButton::isModifierButton() { return false; } void JoyButton::resetActiveButtonMouseDistances(JoyButtonMouseHelper *mouseHelper) { mouseHelper->resetButtonMouseDistances(); } void JoyButton::resetAccelerationDistances() { if (updateLastMouseDistance) { lastAccelerationDistance = currentAccelerationDistance; lastMouseDistance = currentMouseDistance; updateLastMouseDistance = false; } if (updateStartingMouseDistance) { startingAccelerationDistance = lastAccelerationDistance; updateStartingMouseDistance = false; } if (updateOldAccelMulti >= 0.0) { oldAccelMulti = updateOldAccelMulti; updateOldAccelMulti = 0.0; } currentAccelerationDistance = getAccelerationDistance(); currentMouseDistance = getMouseDistanceFromDeadZone(); } void JoyButton::initializeDistanceValues() { lastAccelerationDistance = getLastAccelerationDistance(); currentAccelerationDistance = getAccelerationDistance(); startingAccelerationDistance = lastAccelerationDistance; lastMouseDistance = getLastMouseDistanceFromDeadZone(); currentMouseDistance = getMouseDistanceFromDeadZone(); } double JoyButton::getLastMouseDistanceFromDeadZone() { return lastMouseDistance; } double JoyButton::getLastAccelerationDistance() { return lastAccelerationDistance; } void JoyButton::copyLastMouseDistanceFromDeadZone(JoyButton *srcButton) { this->lastMouseDistance = srcButton->lastMouseDistance; } void JoyButton::copyLastAccelerationDistance(JoyButton *srcButton) { this->lastAccelerationDistance = srcButton->lastAccelerationDistance; } bool JoyButton::isExtraAccelerationEnabled() { return extraAccelerationEnabled; } double JoyButton::getExtraAccelerationMultiplier() { return extraAccelerationMultiplier; } void JoyButton::setExtraAccelerationStatus(bool status) { if (isPartRealAxis()) { extraAccelerationEnabled = status; emit propertyUpdated(); } else { extraAccelerationEnabled = false; } } void JoyButton::setExtraAccelerationMultiplier(double value) { if ((value >= 1.0) && (value <= 200.0)) { extraAccelerationMultiplier = value; emit propertyUpdated(); } } void JoyButton::setMinAccelThreshold(double value) { if ((value >= 1.0) && (value <= 100.0) && (value <= maxMouseDistanceAccelThreshold)) { minMouseDistanceAccelThreshold = value; // emit propertyUpdated(); } } double JoyButton::getMinAccelThreshold() { return minMouseDistanceAccelThreshold; } void JoyButton::setMaxAccelThreshold(double value) { if ((value >= 1.0) && (value <= 100.0) && (value >= minMouseDistanceAccelThreshold)) { maxMouseDistanceAccelThreshold = value; emit propertyUpdated(); } } double JoyButton::getMaxAccelThreshold() { return maxMouseDistanceAccelThreshold; } void JoyButton::setStartAccelMultiplier(double value) { if ((value >= 0.0) && (value <= 100.0)) { startAccelMultiplier = value; emit propertyUpdated(); } } double JoyButton::getStartAccelMultiplier() { return startAccelMultiplier; } void JoyButton::setSpringModeScreen(int screen, int &springModeScreen) { if (screen >= -1) springModeScreen = screen; } void JoyButton::setAccelExtraDuration(double value) { if ((value >= 0.0) && (value <= 5.0)) { accelDuration = value; emit propertyUpdated(); } } double JoyButton::getAccelExtraDuration() { return accelDuration; } bool JoyButton::hasFutureSpringEvents(QList *pendingMouseButtons) { bool result = false; QListIterator iter(*pendingMouseButtons); while (iter.hasNext()) { JoyButton *temp = iter.next(); if (temp->getMouseMode() == MouseSpring) { result = true; iter.toBack(); } } return result; } void JoyButton::setSpringDeadCircleMultiplier(int value) { if ((value >= 0) && (value <= 100)) { springDeadCircleMultiplier = value; emit propertyUpdated(); } } int JoyButton::getSpringDeadCircleMultiplier() { return springDeadCircleMultiplier; } double JoyButton::getCurrentSpringDeadCircle() { return (springDeadCircleMultiplier * 0.01); } void JoyButton::restartLastMouseTime(QElapsedTimer *testOldMouseTime) { testOldMouseTime->restart(); } void JoyButton::setStaticMouseThread(QThread *thread, QTimer *staticMouseEventTimer, QElapsedTimer *testOldMouseTime, int idleMouseRefrRate, JoyButtonMouseHelper *mouseHelper) { int oldInterval = staticMouseEventTimer->interval(); if (oldInterval == 0) oldInterval = idleMouseRefrRate; staticMouseEventTimer->moveToThread(thread); mouseHelper->moveToThread(thread); QMetaObject::invokeMethod(staticMouseEventTimer, "start", Q_ARG(int, oldInterval)); testOldMouseTime->start(); } void JoyButton::indirectStaticMouseThread(QThread *thread, QTimer *staticMouseEventTimer, JoyButtonMouseHelper *mouseHelper) { QMetaObject::invokeMethod(staticMouseEventTimer, "stop"); QMetaObject::invokeMethod(mouseHelper, "changeThread", Q_ARG(QThread *, thread)); } bool JoyButton::shouldInvokeMouseEvents(QList *pendingMouseButtons, QTimer *staticMouseEventTimer, QElapsedTimer *testOldMouseTime) { bool result = false; if ((staticMouseEventTimer->interval() == 0) && (pendingMouseButtons->size() > 0) && staticMouseEventTimer->isActive()) result = true; else if ((testOldMouseTime->elapsed() >= staticMouseEventTimer->interval()) && (pendingMouseButtons->size() > 0) && staticMouseEventTimer->isActive()) result = true; return result; } void JoyButton::invokeMouseEvents(JoyButtonMouseHelper *mouseHelper) { mouseHelper->mouseEvent(); } bool JoyButton::hasActiveSlots() { return !getActiveSlots().isEmpty(); } void JoyButton::setExtraAccelerationCurve(JoyExtraAccelerationCurve curve) { extraAccelCurve = curve; emit propertyUpdated(); } JoyButton::JoyExtraAccelerationCurve JoyButton::getExtraAccelerationCurve() { return extraAccelCurve; } void JoyButton::setUpdateInitAccel(bool state) { this->updateInitAccelValues = state; } QList &JoyButton::getAssignmentsLocal() { return assignments; } QList &JoyButton::getActiveSlotsLocal() { return activeSlots; } AntiMicroX-antimicrox-b300273/src/joybuttontypes/joybutton.h000066400000000000000000000660661471077622000243070ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYBUTTON_H #define JOYBUTTON_H #include "globalvariables.h" #include "joybuttonmousehelper.h" #include "joybuttonslot.h" #include "springmousemoveinfo.h" #include #include #include #include #include #include class VDPad; class SetJoystick; class QXmlStreamReader; class QXmlStreamWriter; // class QThread; class QThreadPool; /** * @brief Represents a single joystick button being part of a SetJoystick * Contains multiple JoyButtonSlots which do the actual mapping. * Also has various static methods for mouse cursor movement. */ class JoyButton : public QObject { Q_OBJECT public: explicit JoyButton(int sdl_button_index, int originset, SetJoystick *parentSet, QObject *parent); ~JoyButton(); enum SetChangeCondition { SetChangeDisabled = 0, SetChangeOneWay, SetChangeTwoWay, SetChangeWhileHeld }; enum JoyMouseMovementMode { MouseCursor = 0, MouseSpring }; enum JoyMouseCurve { EnhancedPrecisionCurve = 0, LinearCurve, QuadraticCurve, CubicCurve, QuadraticExtremeCurve, PowerCurve, EasingQuadraticCurve, EasingCubicCurve }; enum JoyExtraAccelerationCurve { LinearAccelCurve, EaseOutSineCurve, EaseOutQuadAccelCurve, EaseOutCubicAccelCurve }; enum TurboMode { NormalTurbo = 0, GradientTurbo, PulseTurbo }; typedef struct _mouseCursorInfo { JoyButtonSlot *slot; double code; } mouseCursorInfo; void joyEvent(bool pressed, bool ignoresets = false); // JoyButtonEvents class void queuePendingEvent(bool pressed, bool ignoresets = false); // JoyButtonEvents class void activatePendingEvent(); // JoyButtonEvents class void setJoyNumber(int index); void clearPendingEvent(); // JoyButtonEvents class void setCustomName(QString name); void setUpdateInitAccel(bool state); void removeVDPad(); void setIgnoreEventState(bool ignore); // JoyButtonEvents class void setMouseMode(JoyMouseMovementMode mousemode); void setMouseCurve(JoyMouseCurve selectedCurve); void setWhileHeldStatus(bool status); void setCycleResetStatus(bool enabled); void copyAssignments(JoyButton *destButton); void resetAccelerationDistances(); void setExtraAccelerationStatus(bool status); void setExtraAccelerationMultiplier(double value); void setCycleResetTime(int interval); // .., unsigned void setMinAccelThreshold(double value); void setExtraAccelerationCurve(JoyExtraAccelerationCurve curve); void setSpringDeadCircleMultiplier(int value); void setAccelExtraDuration(double value); void setStartAccelMultiplier(double value); void setMaxAccelThreshold(double value); void setChangeSetSelection(int index, bool updateActiveString = true); void activateMiniSlots(JoyButtonSlot *slot, JoyButtonSlot *mix); bool hasPendingEvent(); // JoyButtonEvents class bool getToggleState(); bool isUsingTurbo(); bool getButtonState(); bool containsSequence(); bool containsDistanceSlots(); // JoyButtonSlots class bool containsReleaseSlots(); // JoyButtonSlots class bool getIgnoreEventState(); // JoyButtonEvents class bool getWhileHeldStatus(); bool hasActiveSlots(); // JoyButtonSlots class bool isCycleResetActive(); bool isRelativeSpring(); bool isPartVDPad(); bool isExtraAccelerationEnabled(); double getMinAccelThreshold(); double getMaxAccelThreshold(); double getStartAccelMultiplier(); double getAccelExtraDuration(); double getExtraAccelerationMultiplier(); double getSensitivity(); double getEasingDuration(); int getJoyNumber(); int getTurboInterval(); int getMouseSpeedX(); int getMouseSpeedY(); int getWheelSpeedX(); int getWheelSpeedY(); int getSetSelection(); int getOriginSet(); int getSpringWidth(); int getSpringHeight(); int getCycleResetTime(); // unsigned int getSpringDeadCircleMultiplier(); QString getCustomName(); QString getActionName(); QString getButtonName(); QList *getAssignedSlots(); // JoyButtonSlots class QList const &getActiveSlots(); // JoyButtonSlots class virtual bool isPartRealAxis(); virtual bool isModifierButton(); bool isDefault(); virtual JoyMouseCurve getDefaultMouseCurve() const; virtual int getRealJoyNumber() const; virtual double getDistanceFromDeadZone(); virtual double getMouseDistanceFromDeadZone(); virtual double getLastMouseDistanceFromDeadZone(); virtual double getAccelerationDistance(); virtual double getLastAccelerationDistance(); virtual void initializeDistanceValues(); virtual void setTurboMode(TurboMode mode); virtual void setDefaultButtonName(QString tempname); virtual void copyLastMouseDistanceFromDeadZone( JoyButton *srcButton); // Don't use direct assignment but copying from a current button. virtual void copyLastAccelerationDistance(JoyButton *srcButton); virtual void setVDPad(VDPad *vdpad); virtual void setChangeSetCondition(SetChangeCondition condition, bool passive = false, bool updateActiveString = true); virtual QString getPartialName(bool forceFullFormat = false, bool displayNames = false) const; virtual QString getSlotsSummary(); // JoyButtonSlots class virtual QString getSlotsString(); // JoyButtonSlots class virtual QString getActiveZoneSummary(); virtual QString getCalculatedActiveZoneSummary(); virtual QString getName(bool forceFullFormat = false, bool displayNames = false); virtual QString getXmlName(); // JoyButtonXml class virtual QString getDefaultButtonName(); virtual QList getActiveZoneList(); SetChangeCondition getChangeSetCondition(); VDPad *getVDPad(); JoyMouseMovementMode getMouseMode(); JoyMouseCurve getMouseCurve(); SetJoystick *getParentSet(); TurboMode getTurboMode(); static int calculateFinalMouseSpeed(JoyMouseCurve curve, int value, const float joyspeed); static bool hasCursorEvents(QList *cursorXSpeedsList, QList *cursorYSpeedsList); // JoyButtonEvents class static bool hasSpringEvents(QList *springXSpeedsList, QList *springYSpeedsList); // JoyButtonEvents class static bool shouldInvokeMouseEvents(QList *pendingMouseButtons, QTimer *staticMouseEventTimer, QElapsedTimer *testOldMouseTime); static void setWeightModifier(double modifier, double maxWeightModifier, double &weightModifier); static void moveMouseCursor(int &movedX, int &movedY, int &movedElapsed, QList *mouseHistoryX, QList *mouseHistoryY, QElapsedTimer *testOldMouseTime, QTimer *staticMouseEventTimer, int mouseRefreshRate, int mouseHistorySize, QList *cursorXSpeeds, QList *cursorYSpeeds, double &cursorRemainderX, double &cursorRemainderY, double weightModifier, int idleMouseRefrRate, QList *pendingMouseButtonse); static void moveSpringMouse(int &movedX, int &movedY, bool &hasMoved, int springModeScreen, QList *springXSpeeds, QList *springYSpeeds, QList *pendingMouseButtons, int mouseRefreshRate, int idleMouseRefrRate, QTimer *staticMouseEventTimer); static void setMouseHistorySize(int size, int maxMouseHistSize, int &mouseHistSize, QList *mouseHistoryX, QList *mouseHistoryY); static void setMouseRefreshRate(int refresh, int &mouseRefreshRate, int idleMouseRefrRate, JoyButtonMouseHelper *mouseHelper, QList *mouseHistoryX, QList *mouseHistoryY, QElapsedTimer *testOldMouseTime, QTimer *staticMouseEventTimer); static void setSpringModeScreen(int screen, int &springModeScreen); static void resetActiveButtonMouseDistances(JoyButtonMouseHelper *mouseHelper); static void setGamepadRefreshRate(int refresh, int &gamepadRefreshRate, JoyButtonMouseHelper *mouseHelper); static void restartLastMouseTime(QElapsedTimer *testOldMouseTime); static void setStaticMouseThread(QThread *thread, QTimer *staticMouseEventTimer, QElapsedTimer *testOldMouseTime, int idleMouseRefrRate, JoyButtonMouseHelper *mouseHelper); static void indirectStaticMouseThread(QThread *thread, QTimer *staticMouseEventTimer, JoyButtonMouseHelper *mouseHelper); static void invokeMouseEvents(JoyButtonMouseHelper *mouseHelper); // JoyButtonEvents class static JoyButtonMouseHelper *getMouseHelper(); static QList *getPendingMouseButtons(); static QList *getCursorXSpeeds(); static QList *getCursorYSpeeds(); static QList *getSpringXSpeeds(); static QList *getSpringYSpeeds(); static QTimer *getStaticMouseEventTimer(); // JoyButtonEvents class static QElapsedTimer *getTestOldMouseTime(); JoyExtraAccelerationCurve getExtraAccelerationCurve(); static const JoyMouseCurve DEFAULTMOUSECURVE; static const SetChangeCondition DEFAULTSETCONDITION; static const JoyMouseMovementMode DEFAULTMOUSEMODE; static const TurboMode DEFAULTTURBOMODE; static const JoyExtraAccelerationCurve DEFAULTEXTRAACCELCURVE; bool insertAssignedSlot(JoyButtonSlot *slot, bool updateActiveString = true); // JoyButtonSlots class bool insertAssignedSlot(JoyButtonSlot *newSlot, int index, bool updateActiveString = true); bool containsJoyMixSlot(); protected: int getPreferredKeyPressTime(); // unsigned double getTotalSlotDistance(JoyButtonSlot *slot); bool distanceEvent(); // JoyButtonEvents class bool checkForDelaySequence(); void clearAssignedSlots(bool signalEmit = true); // JoyButtonSlots class void releaseSlotEvent(); // JoyButtonEvents class void checkForPressedSetChange(); void checkTurboCondition(JoyButtonSlot *slot); void vdpadPassEvent(bool pressed, bool ignoresets = false); // JoyButtonEvents class void localBuildActiveZoneSummaryString(); static bool hasFutureSpringEvents(QList *pendingMouseButtons); static int timeBetweenMiniSlots; static int allSlotTimeBetweenSlots; virtual double getCurrentSpringDeadCircle(); TurboMode currentTurboMode; QString buildActiveZoneSummary(QList &tempList); static QList mouseSpeedModList; // JoyButtonSlots class static QList cursorXSpeeds; static QList cursorYSpeeds; static QList springXSpeeds; static QList springYSpeeds; static QList pendingMouseButtons; static JoyButtonSlot *lastActiveKey; // JoyButtonSlots class static JoyButtonMouseHelper mouseHelper; int m_index_sdl; // Used to denote the SDL index of the actual joypad button int turboInterval; int wheelSpeedX; int wheelSpeedY; int setSelection; int tempTurboInterval; int springDeadCircleMultiplier; bool isButtonPressed; // Used to denote whether the actual joypad button is pressed bool isKeyPressed; // Used to denote whether the virtual key is pressed double lastDistance; double lastWheelVerticalDistance; double lastWheelHorizontalDistance; QTimer turboTimer; QTimer mouseWheelVerticalEventTimer; QTimer mouseWheelHorizontalEventTimer; QElapsedTimer wheelVerticalTime; QElapsedTimer wheelHorizontalTime; QElapsedTimer turboHold; QPointer m_parentSet; SetChangeCondition setSelectionCondition; JoyButtonSlot *currentWheelVerticalEvent; // JoyButtonEvents class JoyButtonSlot *currentWheelHorizontalEvent; // JoyButtonEvents class QQueue ignoreSetQueue; QQueue isButtonPressedQueue; QQueue mouseWheelVerticalEventQueue; // JoyButtonEvents class QQueue mouseWheelHorizontalEventQueue; // JoyButtonEvents class QString buttonName; // User specified button name QString defaultButtonName; // Name used by the system signals: void clicked(int index); void released(int index); void keyChanged(int keycode); void mouseChanged(int mousecode); void setChangeActivated(int index); void setAssignmentChanged(int current_button, int associated_set, int mode); void finishedPause(); void turboChanged(bool state); void toggleChanged(bool state); void turboIntervalChanged(int interval); void slotsChanged(); // JoyButtonSlots class void actionNameChanged(); void buttonNameChanged(); void propertyUpdated(); void activeZoneChanged(); public slots: void setTurboInterval(int interval); void setToggle(bool toggle); void setUseTurbo(bool useTurbo); void setMouseSpeedX(int speed); void setMouseSpeedY(int speed); void setWheelSpeed(int speed, QChar ax); void setSpringWidth(int value); void setSpringHeight(int value); void setSensitivity(double value); void setSpringRelativeStatus(bool value); void setActionName(QString tempName); void setButtonName(QString tempName); void setEasingDuration(double value); void establishPropertyUpdatedConnections(); void disconnectPropertyUpdatedConnections(); void removeAssignedSlot(int index); virtual void reset(); virtual void reset(int index); virtual void resetProperties(); virtual void clearSlotsEventReset(bool clearSignalEmit = true); // JoyButtonEvents class virtual void eventReset(); // JoyButtonEvents class virtual void mouseEvent(); // JoyButtonEvents class static void establishMouseTimerConnections(); bool setAssignedSlot(int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); // JoyButtonSlots class bool setAssignedSlot(int code, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); // JoyButtonSlots class bool setAssignedSlot(int code, int alias, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); // JoyButtonSlots class bool setAssignedSlot(JoyButtonSlot *otherSlot, int index); // JoyButtonSlots class bool insertAssignedSlot(int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); // JoyButtonSlots class void buildActiveZoneSummaryString(); protected slots: virtual void turboEvent(); // JoyButtonEvents class virtual void wheelEventVertical(); // JoyButtonEvents class virtual void wheelEventHorizontal(); // JoyButtonEvents class void createDeskEvent(); // JoyButtonEvents class void releaseDeskEvent(bool skipsetchange = false); // JoyButtonEvents class private slots: void releaseActiveSlots(); // JoyButtonSlots class void activateSlots(); // JoyButtonSlots class void waitForDeskEvent(); // JoyButtonEvents class void waitForReleaseDeskEvent(); // JoyButtonEvents class void holdEvent(); // JoyButtonEvents class void delayEvent(); // JoyButtonEvents class void pauseWaitEvent(); // JoyButtonEvents class void checkForSetChange(); void keyPressEvent(); // JoyButtonEvents class void slotSetChange(); private: inline void updatePendingParams(bool isEvent, bool isPressed, bool areIgnoredSets) { pendingEvent = isEvent; pendingPress = isPressed; pendingIgnoreSets = areIgnoredSets; } inline void updateMouseParams(bool updatedLastDist, bool updatedStartDist, double oldAccelMultiVal) { updateLastMouseDistance = updatedLastDist; updateStartingMouseDistance = updatedStartDist; updateOldAccelMulti = oldAccelMultiVal; } inline void resetSlotsProp(bool currentChangedSlot = false) // JoyButtonSlots class { currentCycle = nullptr; previousCycle = nullptr; currentPause = nullptr; currentHold = nullptr; m_currentDistance = nullptr; currentRawValue = 0; currentMouseEvent = nullptr; currentRelease = nullptr; currentWheelVerticalEvent = nullptr; currentWheelHorizontalEvent = nullptr; currentKeyPress = nullptr; currentDelay = nullptr; if (currentChangedSlot) currentSetChangeSlot = nullptr; isKeyPressed = isButtonPressed = false; quitEvent = true; } inline void stopTimers(bool stoppedSlotSetTimer) { turboTimer.stop(); pauseWaitTimer.stop(); createDeskTimer.stop(); releaseDeskTimer.stop(); holdTimer.stop(); mouseWheelVerticalEventTimer.stop(); mouseWheelHorizontalEventTimer.stop(); setChangeTimer.stop(); keyPressTimer.stop(); delayTimer.stop(); if (stoppedSlotSetTimer) slotSetChangeTimer.stop(); if (slotiter != nullptr) { delete slotiter; slotiter = nullptr; } } inline void clearQueues() { isButtonPressedQueue.clear(); ignoreSetQueue.clear(); mouseEventQueue.clear(); mouseWheelVerticalEventQueue.clear(); mouseWheelHorizontalEventQueue.clear(); } inline void restartAccelParams(bool updatedOldAccel, bool restartedAccelDurTimer, bool restartedRestParams) { lastAccelerationDistance = 0.0; currentAccelMulti = 0.0; currentAccelerationDistance = 0.0; startingAccelerationDistance = 0.0; if (updatedOldAccel) oldAccelMulti = updateOldAccelMulti = 0.0; else oldAccelMulti = 0.0; accelTravel = 0.0; if (restartedAccelDurTimer) accelExtraDurationTime.restart(); if (restartedRestParams) { updateInitAccelValues = true; extraAccelerationEnabled = false; extraAccelerationMultiplier = GlobalVariables::JoyButton::DEFAULTEXTRACCELVALUE; minMouseDistanceAccelThreshold = GlobalVariables::JoyButton::DEFAULTMINACCELTHRESHOLD; maxMouseDistanceAccelThreshold = GlobalVariables::JoyButton::DEFAULTMAXACCELTHRESHOLD; startAccelMultiplier = GlobalVariables::JoyButton::DEFAULTSTARTACCELMULTIPLIER; accelDuration = GlobalVariables::JoyButton::DEFAULTACCELEASINGDURATION; extraAccelCurve = DEFAULTEXTRAACCELCURVE; } } inline void lockForWritedString(QString ¶m, QString value) { activeZoneStringLock.lockForWrite(); param = value; activeZoneStringLock.unlock(); } void releaseEachSlot(bool &changeRepeatState, int &references, int tempcode, JoyButtonSlot::JoySlotInputAction mode, JoyButtonSlot *slot); void resetAllProperties(); void resetPrivVars(); void restartAllForSetChange(); void startTimerOverrun(int slotCode, QElapsedTimer *currSlotTime, QTimer *currSlotTimer, bool releasedDeskTimer = false); void findJoySlotsEnd(QListIterator *slotiter); void changeStatesQueue(bool currentReleased); void countActiveSlots(int tempcode, int &references, JoyButtonSlot *slot, QHash &activeSlotsHash, bool &changeRepeatState, bool activeSlotHashWindows = false); // JoyButtonSlots class void releaseMoveSlots(QList &cursorSpeeds, JoyButtonSlot *slot, QList &indexesToRemove); // JoyButtonSlots class void setSpringDeadCircle(double &springDeadCircle, int mouseDirection); void checkSpringDeadCircle(int tempcode, double &springDeadCircle, int mouseSlot1, int mouseSlot2); static void distanceForMovingAx(double &finalAx, mouseCursorInfo infoAx); static void adjustAxForCursor(QList *mouseHistoryList, double &adjustedAx, double &cursorRemainder, double weightModifier); void setDistanceForSpring(JoyButtonMouseHelper &mouseHelper, double &mouseFirstAx, double &mouseSecondAx, double distanceFromDeadZone); void changeTurboParams(bool _isKeyPressed, bool isButtonPressed); void updateParamsAfterDistEvent(); // JoyButtonEvents class void startSequenceOfPressActive(bool isTurbo, QString debugText); QList &getAssignmentsLocal(); QList &getActiveSlotsLocal(); // JoyButtonSlots class void updateMouseProperties(double newAxisValue, double newSpringDead, int newSpringWidth, int newSpringHeight, bool relatived, int modeScreen, QList &springSpeeds, QChar axis, double newAxisValueY = 0, double newSpringDeadY = 0); // void getActiveZoneWithAppend(JoyButtonSlot::JoySlotInputAction mode, QList& tempSlotList, // QListIterator *iter, JoyButtonSlot *slot); void buildActiveZoneSummarySwitchSlots(JoyButtonSlot::JoySlotInputAction mode, JoyButtonSlot *slot, bool &behindHold, QStringList *stringlist, int &i, QListIterator *iter, bool slotsActive); bool m_toggle; bool quitEvent; // JoyButtonEvents class bool isDown; bool toggleActiveState; bool m_useTurbo; bool lastUnlessInList; bool m_ignoresets; bool ignoreEvents; // JoyButtonEvents class bool whileHeldStatus; bool updateLastMouseDistance; // Should lastMouseDistance be updated. Set after mouse event. bool updateStartingMouseDistance; // Should startingMouseDistance be updated. Set after acceleration has finally been // applied. bool relativeSpring; bool pendingPress; bool pendingEvent; // JoyButtonEvents class bool pendingIgnoreSets; bool extraAccelerationEnabled; bool cycleResetActive; bool updateInitAccelValues; int mouseSpeedX; int mouseSpeedY; int m_originset; int springWidth; int springHeight; int currentRawValue; int cycleResetInterval; // unsigned double sensitivity; double lastMouseDistance; // Keep track of the previous mouse distance from the previous gamepad poll. double lastAccelerationDistance; // Keep track of the previous full distance from the previous gamepad poll double currentAccelMulti; // Multiplier and time used for acceleration easing. double accelDuration; double oldAccelMulti; double accelTravel; // Track travel when accel started double updateOldAccelMulti; double currentMouseDistance; // Keep track of the current mouse distance after a poll. Used to update lastMouseDistance // later. double currentAccelerationDistance; // Keep track of the current mouse distance after a poll. Used to update // lastMouseDistance later. double startingAccelerationDistance; // Take into account when mouse acceleration started double minMouseDistanceAccelThreshold; double maxMouseDistanceAccelThreshold; double startAccelMultiplier; double m_easingDuration; double extraAccelerationMultiplier; QTimer pauseTimer; QTimer holdTimer; QTimer pauseWaitTimer; QTimer createDeskTimer; QTimer releaseDeskTimer; QTimer setChangeTimer; QTimer keyPressTimer; QTimer delayTimer; QTimer slotSetChangeTimer; static QTimer staticMouseEventTimer; // JoyButtonEvents class QString customName; QString actionName; QString activeZoneString; QList assignments; QList activeSlots; QListIterator *slotiter; QQueue mouseEventQueue; // JoyButtonEvents class JoyButtonSlot *currentPause; JoyButtonSlot *currentHold; JoyButtonSlot *currentCycle; JoyButtonSlot *previousCycle; JoyButtonSlot *m_currentDistance; JoyButtonSlot *currentMouseEvent; // JoyButtonEvents class JoyButtonSlot *currentRelease; JoyButtonSlot *currentKeyPress; JoyButtonSlot *currentDelay; JoyButtonSlot *currentSetChangeSlot; QElapsedTimer buttonHold; QElapsedTimer pauseHold; QElapsedTimer inpauseHold; QElapsedTimer buttonHeldRelease; QElapsedTimer keyPressHold; QElapsedTimer buttonDelay; QElapsedTimer accelExtraDurationTime; QElapsedTimer cycleResetHold; static QElapsedTimer testOldMouseTime; VDPad *m_vdpad; JoyMouseMovementMode mouseMode; JoyMouseCurve mouseCurve; JoyExtraAccelerationCurve extraAccelCurve; QReadWriteLock activeZoneLock; QReadWriteLock assignmentsLock; QReadWriteLock activeZoneStringLock; QThreadPool *threadPool; void addEachSlotToActives(JoyButtonSlot *slot, int &i, bool &delaySequence, bool &exit, QListIterator *slotiter); }; class MiniSlotRun : public QRunnable, public QObject { public: MiniSlotRun(JoyButtonSlot *slot, JoyButtonSlot *slotmini, JoyButton *btn, int milisec) : QObject(btn) , m_slot(slot) , m_slotmini(slotmini) , m_btn(btn) , m_miliseconds(milisec) { } ~MiniSlotRun() {} void run() { this->thread()->wait(m_miliseconds); m_btn->activateMiniSlots(m_slotmini, m_slot); } private: JoyButtonSlot *m_slot; JoyButtonSlot *m_slotmini; JoyButton *m_btn; int m_miliseconds; }; #endif // JOYBUTTON_H AntiMicroX-antimicrox-b300273/src/joybuttontypes/joycontrolstickbutton.cpp000066400000000000000000000201241471077622000272620ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joycontrolstickbutton.h" #include "event.h" #include "globalvariables.h" #include "joycontrolstick.h" #include "joycontrolstickmodifierbutton.h" #include "setjoystick.h" #include #include #include JoyControlStickButton::JoyControlStickButton(JoyControlStick *stick, int index, int originset, SetJoystick *parentSet, QObject *parent) : JoyGradientButton(index, originset, parentSet, parent) { this->stick = stick; } JoyControlStickButton::JoyControlStickButton(JoyControlStick *stick, JoyStickDirectionsType::JoyStickDirections index, int originset, SetJoystick *parentSet, QObject *parent) : JoyGradientButton(index, originset, parentSet, parent) { this->stick = stick; } QString JoyControlStickButton::getDirectionName() const { QString label = QString(); switch (m_index_sdl) { case 1: label.append(tr("Up")); break; case 2: label.append(tr("Up")).append("+").append(tr("Right")); break; case 3: label.append(tr("Right")); break; case 4: label.append(tr("Down")).append("+").append(tr("Right")); break; case 5: label.append(tr("Down")); break; case 6: label.append(tr("Down")).append("+").append(tr("Left")); break; case 7: label.append(tr("Left")); break; case 8: label.append(tr("Up")).append("+").append(tr("Left")); break; } return label; } QString JoyControlStickButton::getPartialName(bool forceFullFormat, bool displayNames) const { QString temp = stick->getPartialName(forceFullFormat, displayNames); temp.append(": "); if (!buttonName.isEmpty() && displayNames) { if (forceFullFormat) { temp.append(tr("Button")).append(" "); } temp.append(buttonName); } else if (!defaultButtonName.isEmpty()) { if (forceFullFormat) { temp.append(tr("Button")).append(" "); } temp.append(defaultButtonName); } else { temp.append(tr("Button")).append(" "); temp.append(getDirectionName()); } return temp; } QString JoyControlStickButton::getXmlName() { return GlobalVariables::JoyControlStickButton::xmlName; } /** * @brief Get the distance that an element is away from its assigned * dead zone * @return Normalized distance away from dead zone */ double JoyControlStickButton::getDistanceFromDeadZone() { return stick->calculateDirectionalDistance(); } /** * @brief Get the distance factor that should be used for mouse movement * @return Distance factor that should be used for mouse movement */ double JoyControlStickButton::getMouseDistanceFromDeadZone() { return stick->calculateMouseDirectionalDistance(this); } void JoyControlStickButton::setChangeSetCondition(SetChangeCondition condition, bool passive, bool updateActiveString) { Q_UNUSED(updateActiveString); SetChangeCondition oldCondition = setSelectionCondition; if ((condition != setSelectionCondition) && !passive) { if ((condition == SetChangeWhileHeld) || (condition == SetChangeTwoWay)) { // Set new condition emit setAssignmentChanged(m_index_sdl, this->stick->getIndex(), setSelection, condition); } else if ((setSelectionCondition == SetChangeWhileHeld) || (setSelectionCondition == SetChangeTwoWay)) { // Remove old condition emit setAssignmentChanged(m_index_sdl, this->stick->getIndex(), setSelection, SetChangeDisabled); } setSelectionCondition = condition; } else if (passive) { setSelectionCondition = condition; } if (setSelectionCondition == SetChangeDisabled) { setChangeSetSelection(-1); } if (setSelectionCondition != oldCondition) { buildActiveZoneSummaryString(); emit propertyUpdated(); } } int JoyControlStickButton::getRealJoyNumber() const { return m_index_sdl; } JoyStickDirectionsType::JoyStickDirections JoyControlStickButton::getDirection() const { return static_cast(m_index_sdl); } /** * @brief Set the turbo mode that the button should use * @param Mode that should be used */ void JoyControlStickButton::setTurboMode(TurboMode mode) { if (isPartRealAxis()) { currentTurboMode = mode; } } /** * @brief Check if button should be considered a part of a real controller * axis. Needed for some dialogs so the program won't have to resort to * type checking. * @return Status of being part of a real controller axis */ bool JoyControlStickButton::isPartRealAxis() { return true; } double JoyControlStickButton::getLastAccelerationDistance() { double temp = stick->calculateLastAccelerationButtonDistance(this); return temp; } double JoyControlStickButton::getAccelerationDistance() { double temp = stick->calculateAccelerationDistance(this); return temp; } /** * @brief Generate a string that represents slots that will be activated or * slots that are currently active if a button is pressed * @return String of currently applicable slots for a button */ QString JoyControlStickButton::getActiveZoneSummary() { QList tempList; tempList.append(getActiveZoneList()); QString temp = buildActiveZoneSummary(tempList); return temp; } QString JoyControlStickButton::getCalculatedActiveZoneSummary() { JoyControlStickModifierButton *tempButton = stick->getModifierButton(); QString temp = QString(); QStringList stringlist = QStringList(); if ((tempButton != nullptr) && tempButton->getButtonState() && tempButton->hasActiveSlots() && getButtonState()) { qDebug() << "Calculated Active Zone Summary: " << tempButton->getCalculatedActiveZoneSummary(); stringlist.append(tempButton->getCalculatedActiveZoneSummary()); } stringlist.append(JoyButton::getCalculatedActiveZoneSummary()); temp = stringlist.join(", "); qDebug() << "Returned joined zone: " << temp; return temp; } double JoyControlStickButton::getLastMouseDistanceFromDeadZone() { return stick->calculateLastMouseDirectionalDistance(this); } double JoyControlStickButton::getCurrentSpringDeadCircle() { double result = (springDeadCircleMultiplier * 0.01); if ((m_index_sdl == static_cast(JoyControlStick::StickLeft)) || (m_index_sdl == static_cast(JoyControlStick::StickRight))) { result = stick->getSpringDeadCircleX() * (springDeadCircleMultiplier * 0.01); } else if ((m_index_sdl == static_cast(JoyControlStick::StickUp)) || (m_index_sdl == static_cast(JoyControlStick::StickDown))) { result = stick->getSpringDeadCircleY() * (springDeadCircleMultiplier * 0.01); } else if ((m_index_sdl == static_cast(JoyControlStick::StickRightUp)) || (m_index_sdl == static_cast(JoyControlStick::StickRightDown)) || (m_index_sdl == static_cast(JoyControlStick::StickLeftDown)) || (m_index_sdl == static_cast(JoyControlStick::StickLeftUp))) { result = 0.0; } return result; } JoyControlStick *JoyControlStickButton::getStick() const { return stick; } AntiMicroX-antimicrox-b300273/src/joybuttontypes/joycontrolstickbutton.h000066400000000000000000000050361471077622000267340ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYCONTROLSTICKBUTTON_H #define JOYCONTROLSTICKBUTTON_H #include "joybuttontypes/joygradientbutton.h" #include "joycontrolstickdirectionstype.h" class JoyControlStick; class SetJoystick; class JoyControlStickButton : public JoyGradientButton { Q_OBJECT public: explicit JoyControlStickButton(JoyControlStick *stick, int index, int originset, SetJoystick *parentSet, QObject *parent); explicit JoyControlStickButton(JoyControlStick *stick, JoyStickDirectionsType::JoyStickDirections index, int originset, SetJoystick *parentSet, QObject *parent); virtual int getRealJoyNumber() const; virtual QString getPartialName(bool forceFullFormat = false, bool displayNames = false) const; virtual QString getXmlName(); virtual double getDistanceFromDeadZone(); virtual double getMouseDistanceFromDeadZone(); virtual double getLastMouseDistanceFromDeadZone(); virtual void setChangeSetCondition(SetChangeCondition condition, bool passive = false, bool updateActiveString = true); virtual void setTurboMode(TurboMode mode); virtual bool isPartRealAxis(); virtual QString getActiveZoneSummary(); virtual QString getCalculatedActiveZoneSummary(); virtual double getAccelerationDistance(); virtual double getLastAccelerationDistance(); JoyControlStick *getStick() const; QString getDirectionName() const; JoyStickDirectionsType::JoyStickDirections getDirection() const; protected: virtual double getCurrentSpringDeadCircle(); signals: void setAssignmentChanged(int current_button, int axis_index, int associated_set, int mode); private: JoyControlStick *stick; }; #endif // JOYCONTROLSTICKBUTTON_H AntiMicroX-antimicrox-b300273/src/joybuttontypes/joycontrolstickmodifierbutton.cpp000066400000000000000000000076441471077622000310150ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joycontrolstickmodifierbutton.h" #include "globalvariables.h" #include "joycontrolstick.h" #include "setjoystick.h" #include #include #include JoyControlStickModifierButton::JoyControlStickModifierButton(JoyControlStick *stick, int originset, SetJoystick *parentSet, QObject *parent) : JoyGradientButton(0, originset, parentSet, parent) { this->stick = stick; } QString JoyControlStickModifierButton::getPartialName(bool forceFullFormat, bool displayNames) const { QString temp = stick->getPartialName(forceFullFormat, displayNames); temp.append(": "); if (!buttonName.isEmpty() && displayNames) { if (forceFullFormat) { temp.append(tr("Modifier")).append(" "); } temp.append(buttonName); } else if (!defaultButtonName.isEmpty()) { if (forceFullFormat) { temp.append(tr("Modifier")).append(" "); } temp.append(defaultButtonName); } else { temp.append(tr("Modifier")); } return temp; } QString JoyControlStickModifierButton::getXmlName() { return GlobalVariables::JoyControlStickModifierButton::xmlName; } /** * @brief Get the distance that an element is away from its assigned * dead zone * @return Normalized distance away from dead zone */ double JoyControlStickModifierButton::getDistanceFromDeadZone() { return stick->calculateDirectionalDistance(); } /** * @brief Get the distance factor that should be used for mouse movement * @return Distance factor that should be used for mouse movement */ double JoyControlStickModifierButton::getMouseDistanceFromDeadZone() { return getDistanceFromDeadZone(); } void JoyControlStickModifierButton::setChangeSetCondition(SetChangeCondition condition, bool passive, bool updateActiveString) { Q_UNUSED(updateActiveString); Q_UNUSED(condition); Q_UNUSED(passive); } JoyControlStick *JoyControlStickModifierButton::getStick() const { return stick; } /** * @brief Set the turbo mode that the button should use * @param Mode that should be used */ void JoyControlStickModifierButton::setTurboMode(TurboMode mode) { if (isPartRealAxis()) { currentTurboMode = mode; } } /** * @brief Check if button should be considered a part of a real controller * axis. Needed for some dialogs so the program won't have to resort to * type checking. * @return Status of being part of a real controller axis */ bool JoyControlStickModifierButton::isPartRealAxis() { return true; } bool JoyControlStickModifierButton::isModifierButton() { return true; } double JoyControlStickModifierButton::getAccelerationDistance() { double temp = stick->getAbsoluteRawDistance(); return temp; } double JoyControlStickModifierButton::getLastAccelerationDistance() { double temp = stick->calculateLastAccelerationDirectionalDistance(); return temp; } double JoyControlStickModifierButton::getLastMouseDistanceFromDeadZone() { return stick->calculateLastDirectionalDistance(); } AntiMicroX-antimicrox-b300273/src/joybuttontypes/joycontrolstickmodifierbutton.h000066400000000000000000000036461471077622000304600ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYCONTROLSTICKMODIFIERBUTTON_H #define JOYCONTROLSTICKMODIFIERBUTTON_H #include "joybuttontypes/joygradientbutton.h" class JoyControlStick; class SetJoystick; class JoyControlStickModifierButton : public JoyGradientButton { Q_OBJECT public: explicit JoyControlStickModifierButton(JoyControlStick *stick, int originset, SetJoystick *parentSet, QObject *parent); virtual QString getPartialName(bool forceFullFormat = false, bool displayNames = false) const; virtual QString getXmlName(); virtual double getDistanceFromDeadZone(); virtual double getMouseDistanceFromDeadZone(); virtual double getLastMouseDistanceFromDeadZone(); virtual void setChangeSetCondition(SetChangeCondition condition, bool passive = false, bool updateActiveString = true); virtual void setTurboMode(TurboMode mode); virtual bool isPartRealAxis(); virtual bool isModifierButton(); virtual double getAccelerationDistance(); virtual double getLastAccelerationDistance(); JoyControlStick *getStick() const; private: JoyControlStick *stick; }; #endif // JOYCONTROLSTICKMODIFIERBUTTON_H AntiMicroX-antimicrox-b300273/src/joybuttontypes/joydpadbutton.cpp000066400000000000000000000101621471077622000254550ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joydpadbutton.h" #include "event.h" #include "globalvariables.h" #include "joydpad.h" #include "setjoystick.h" #include // Initially, qualify direction as the button's index JoyDPadButton::JoyDPadButton(int direction, int originset, JoyDPad *dpad, SetJoystick *parentSet, QObject *parent) : JoyButton(direction, originset, parentSet, parent) { m_direction = direction; m_dpad = dpad; } QString JoyDPadButton::getDirectionName() const { QString label = QString(); switch (m_direction) { case 1: label.append(tr("Up")); break; case 2: label.append(tr("Right")); break; case 3: label.append(tr("Up")).append("+").append(tr("Right")); break; case 4: label.append(tr("Down")); break; case 6: label.append(tr("Down")).append("+").append(tr("Right")); break; case 8: label.append(tr("Left")); break; case 9: label.append(tr("Up")).append("+").append(tr("Left")); break; case 12: label.append(tr("Down")).append("+").append(tr("Left")); break; } return label; } QString JoyDPadButton::getXmlName() { return GlobalVariables::JoyDPadButton::xmlName; } int JoyDPadButton::getRealJoyNumber() const { return m_index_sdl; } QString JoyDPadButton::getPartialName(bool forceFullFormat, bool displayNames) const { QString temp = m_dpad->getName().append(" - "); if (!buttonName.isEmpty() && displayNames) { if (forceFullFormat) { temp.append(tr("Button")).append(" "); } temp.append(buttonName); } else if (!defaultButtonName.isEmpty() && displayNames) { if (forceFullFormat) { temp.append(tr("Button")).append(" "); } temp.append(defaultButtonName); } else { temp.append(tr("Button")).append(" "); temp.append(getDirectionName()); } return temp; } void JoyDPadButton::reset() { JoyButton::reset(); } void JoyDPadButton::reset(int index) { Q_UNUSED(index); reset(); } void JoyDPadButton::setChangeSetCondition(SetChangeCondition condition, bool passive, bool updateActiveString) { Q_UNUSED(updateActiveString); SetChangeCondition oldCondition = setSelectionCondition; if ((condition != setSelectionCondition) && !passive) { if ((condition == SetChangeWhileHeld) || (condition == SetChangeTwoWay)) { // Set new condition emit setAssignmentChanged(m_index_sdl, m_dpad->getJoyNumber(), setSelection, condition); } else if ((setSelectionCondition == SetChangeWhileHeld) || (setSelectionCondition == SetChangeTwoWay)) { // Remove old condition emit setAssignmentChanged(m_index_sdl, m_dpad->getJoyNumber(), setSelection, SetChangeDisabled); } setSelectionCondition = condition; } else if (passive) { setSelectionCondition = condition; } if (setSelectionCondition == SetChangeDisabled) { setChangeSetSelection(-1); } if (setSelectionCondition != oldCondition) { buildActiveZoneSummaryString(); emit propertyUpdated(); } } JoyDPad *JoyDPadButton::getDPad() const { return m_dpad; } int JoyDPadButton::getDirection() const { return m_direction; } AntiMicroX-antimicrox-b300273/src/joybuttontypes/joydpadbutton.h000066400000000000000000000041061471077622000251230ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYDPADBUTTON_H #define JOYDPADBUTTON_H #include "joybutton.h" class JoyDPad; class SetJoystick; class JoyDPadButton : public JoyButton { Q_OBJECT public: JoyDPadButton(int direction, int originset, JoyDPad *dpad, SetJoystick *parentSet, QObject *parent); virtual int getRealJoyNumber() const override; virtual QString getPartialName(bool forceFullFormat = false, bool displayNames = false) const override; virtual QString getXmlName() override; virtual void setChangeSetCondition(SetChangeCondition condition, bool passive = false, bool updateActiveString = true) override; enum JoyDPadDirections { DpadCentered = 0, DpadUp = 1, DpadRight = 2, DpadDown = 4, DpadLeft = 8, DpadRightUp = 3, DpadRightDown = 6, DpadLeftUp = 9, DpadLeftDown = 12 }; QString getDirectionName() const; int getDirection() const; JoyDPad *getDPad() const; signals: void setAssignmentChanged(int current_button, int dpad_index, int associated_set, int mode); public slots: virtual void reset() override; virtual void reset(int index) override; private: int m_direction; JoyDPad *m_dpad; }; #endif // JOYDPADBUTTON_H AntiMicroX-antimicrox-b300273/src/joybuttontypes/joygradientbutton.cpp000066400000000000000000000376361471077622000263610ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joygradientbutton.h" #include "event.h" #include "setjoystick.h" #include #include JoyGradientButton::JoyGradientButton(int sdl_button_index, int originset, SetJoystick *parentSet, QObject *parent) : JoyButton(sdl_button_index, originset, parentSet, parent) { } /** * @brief Activate a turbo event on a button. */ void JoyGradientButton::turboEvent() { int m_turboInterval = containsJoyMixSlot() && allSlotTimeBetweenSlots > 0 ? allSlotTimeBetweenSlots : turboInterval; if (getTurboMode() == NormalTurbo) { JoyButton::turboEvent(); } else if ((getTurboMode() == GradientTurbo) || (getTurboMode() == PulseTurbo)) { double diff = fabs(getMouseDistanceFromDeadZone() - lastDistance); qDebug() << "DIFF: " << QString::number(diff); bool changeState = false; if (!turboTimer.isActive() && !isButtonPressed) { changeState = true; } else if ((getTurboMode() == GradientTurbo) && (diff > 0) && (getMouseDistanceFromDeadZone() >= 1.0)) { if (isKeyPressed) { changeState = false; if (!turboTimer.isActive() || (turboTimer.interval() != 5)) { turboTimer.start(5); } turboHold.restart(); lastDistance = 1.0; } else { changeState = true; } } else if (lastDistance == 0.0 || (turboHold.elapsed() > tempTurboInterval)) { changeState = true; } else if (diff >= 0.1) { int tempInterval2 = 0; if (isKeyPressed) { if (getTurboMode() == GradientTurbo) { tempInterval2 = floor((getMouseDistanceFromDeadZone() * m_turboInterval) + 0.5); } else { tempInterval2 = floor((m_turboInterval * 0.5) + 0.5); } } else { if (getTurboMode() == GradientTurbo) { tempInterval2 = floor(((1 - getMouseDistanceFromDeadZone()) * m_turboInterval) + 0.5); } else { double distance = getMouseDistanceFromDeadZone(); if (distance > 0.0) { tempInterval2 = floor(((m_turboInterval / getMouseDistanceFromDeadZone()) * 0.5) + 0.5); } else { tempInterval2 = 0; } } } if (turboHold.elapsed() < tempInterval2) { // Still some valid time left. Continue current action with // remaining time left. tempTurboInterval = tempInterval2 - turboHold.elapsed(); int timerInterval = qMin(tempTurboInterval, 5); if (!turboTimer.isActive() || (turboTimer.interval() != timerInterval)) { turboTimer.start(timerInterval); } turboHold.restart(); changeState = false; lastDistance = getMouseDistanceFromDeadZone(); qDebug() << "diff tmpTurbo press: " << QString::number(tempTurboInterval); qDebug() << "diff timer press: " << QString::number(timerInterval); } else { changeState = true; qDebug() << "YOU GOT CHANGE"; } } if (changeState) { if (!isKeyPressed) { if (!isButtonPressedQueue.isEmpty()) { ignoreSetQueue.clear(); isButtonPressedQueue.clear(); ignoreSetQueue.enqueue(false); isButtonPressedQueue.enqueue(isButtonPressed); } createDeskEvent(); isKeyPressed = true; if (turboTimer.isActive()) { if (getTurboMode() == GradientTurbo) { tempTurboInterval = floor((getMouseDistanceFromDeadZone() * m_turboInterval) + 0.5); } else { tempTurboInterval = floor((m_turboInterval * 0.5) + 0.5); } int timerInterval = qMin(tempTurboInterval, 5); qDebug() << "tmpTurbo press: " << QString::number(tempTurboInterval); qDebug() << "timer press: " << QString::number(timerInterval); if (turboTimer.interval() != timerInterval) { turboTimer.start(timerInterval); } turboHold.restart(); } } else { if (!isButtonPressedQueue.isEmpty()) { ignoreSetQueue.enqueue(false); isButtonPressedQueue.enqueue(!isButtonPressed); } releaseDeskEvent(); isKeyPressed = false; if (turboTimer.isActive()) { if (getTurboMode() == GradientTurbo) { tempTurboInterval = floor(((1 - getMouseDistanceFromDeadZone()) * m_turboInterval) + 0.5); } else { double distance = getMouseDistanceFromDeadZone(); if (distance > 0.0) { tempTurboInterval = floor(((m_turboInterval / getMouseDistanceFromDeadZone()) * 0.5) + 0.5); } else { tempTurboInterval = 0; } } int timerInterval = qMin(tempTurboInterval, 5); qDebug() << "tmpTurbo release: " << QString::number(tempTurboInterval); qDebug() << "timer release: " << QString::number(timerInterval); if (turboTimer.interval() != timerInterval) { turboTimer.start(timerInterval); } turboHold.restart(); } } lastDistance = getMouseDistanceFromDeadZone(); } } } void JoyGradientButton::wheelEventVertical() { JoyButtonSlot *buttonslot = nullptr; bool activateEvent = false; int tempInterval = 0; double diff = fabs(getMouseDistanceFromDeadZone() - lastWheelVerticalDistance); int oldInterval = 0; if (wheelSpeedY != 0) { if (lastWheelVerticalDistance > 0.0) { oldInterval = 1000 / wheelSpeedY / lastWheelVerticalDistance; } else { oldInterval = 1000 / wheelSpeedY / 0.01; } } if (currentWheelVerticalEvent != nullptr) { buttonslot = currentWheelVerticalEvent; activateEvent = true; } if (!activateEvent) { if (!mouseWheelVerticalEventTimer.isActive()) { activateEvent = true; } else if (wheelVerticalTime.elapsed() > oldInterval) { activateEvent = true; } else if ((diff >= 0.1) && (wheelSpeedY != 0)) { double distance = getMouseDistanceFromDeadZone(); if (distance > 0.0) { tempInterval = 1000 / wheelSpeedY / distance; } else { tempInterval = 0; } if (wheelVerticalTime.elapsed() < tempInterval) { // Still some valid time left. Continue current action with // remaining time left. tempInterval = tempInterval - wheelVerticalTime.elapsed(); tempInterval = qMin(tempInterval, 5); if (!mouseWheelVerticalEventTimer.isActive() || (mouseWheelVerticalEventTimer.interval() != tempInterval)) { mouseWheelVerticalEventTimer.start(tempInterval); } } else { // Elapsed time is greater than new interval. Change state. activateEvent = true; } } } if ((buttonslot != nullptr) && (wheelSpeedY != 0)) { bool isActive = getActiveSlots().contains(buttonslot); if (isActive && activateEvent) { sendevent(buttonslot, true); sendevent(buttonslot, false); mouseWheelVerticalEventQueue.enqueue(buttonslot); double distance = getMouseDistanceFromDeadZone(); if (distance > 0.0) { tempInterval = 1000 / wheelSpeedY / distance; } else { tempInterval = 0; } tempInterval = qMin(tempInterval, 5); if (!mouseWheelVerticalEventTimer.isActive() || (mouseWheelVerticalEventTimer.interval() != tempInterval)) { mouseWheelVerticalEventTimer.start(tempInterval); } } else if (!isActive) { mouseWheelVerticalEventTimer.stop(); } } else if (!mouseWheelVerticalEventQueue.isEmpty() && (wheelSpeedY != 0)) { QQueue tempQueue; while (!mouseWheelVerticalEventQueue.isEmpty()) { buttonslot = mouseWheelVerticalEventQueue.dequeue(); bool isActive = getActiveSlots().contains(buttonslot); if (isActive && activateEvent) { sendevent(buttonslot, true); sendevent(buttonslot, false); tempQueue.enqueue(buttonslot); } else if (isActive) { tempQueue.enqueue(buttonslot); } } if (!tempQueue.isEmpty()) { mouseWheelVerticalEventQueue = tempQueue; double distance = getMouseDistanceFromDeadZone(); if (distance > 0.0) { tempInterval = 1000 / wheelSpeedY / distance; } else { tempInterval = 0; } tempInterval = qMin(tempInterval, 5); if (!mouseWheelVerticalEventTimer.isActive() || (mouseWheelVerticalEventTimer.interval() != tempInterval)) { mouseWheelVerticalEventTimer.start(tempInterval); } } else { mouseWheelVerticalEventTimer.stop(); } } else { mouseWheelVerticalEventTimer.stop(); } if (activateEvent) { wheelVerticalTime.restart(); lastWheelVerticalDistance = getMouseDistanceFromDeadZone(); } } void JoyGradientButton::wheelEventHorizontal() { JoyButtonSlot *buttonslot = nullptr; bool activateEvent = false; int tempInterval = 0; double diff = fabs(getMouseDistanceFromDeadZone() - lastWheelHorizontalDistance); int oldInterval = 0; if (wheelSpeedX != 0) { if (lastWheelHorizontalDistance > 0.0) { oldInterval = 1000 / wheelSpeedX / lastWheelHorizontalDistance; } else { oldInterval = 1000 / wheelSpeedX / 0.01; } } if (currentWheelHorizontalEvent != nullptr) { buttonslot = currentWheelHorizontalEvent; activateEvent = true; } if (!activateEvent) { if (!mouseWheelHorizontalEventTimer.isActive()) { activateEvent = true; } else if (wheelHorizontalTime.elapsed() > oldInterval) { activateEvent = true; } else if ((diff >= 0.1) && (wheelSpeedX != 0)) { double distance = getMouseDistanceFromDeadZone(); if (distance > 0.0) { tempInterval = 1000 / wheelSpeedX / distance; } else { tempInterval = 0; } if (wheelHorizontalTime.elapsed() < tempInterval) { // Still some valid time left. Continue current action with // remaining time left. tempInterval = tempInterval - wheelHorizontalTime.elapsed(); tempInterval = qMin(tempInterval, 5); if (!mouseWheelHorizontalEventTimer.isActive() || (mouseWheelHorizontalEventTimer.interval() != tempInterval)) { mouseWheelHorizontalEventTimer.start(tempInterval); } } else { // Elapsed time is greater than new interval. Change state. activateEvent = true; } } } if ((buttonslot != nullptr) && (wheelSpeedX != 0)) { bool isActive = getActiveSlots().contains(buttonslot); if (isActive && activateEvent) { sendevent(buttonslot, true); sendevent(buttonslot, false); mouseWheelHorizontalEventQueue.enqueue(buttonslot); double distance = getMouseDistanceFromDeadZone(); if (distance > 0.0) { tempInterval = 1000 / wheelSpeedX / distance; } else { tempInterval = 0; } tempInterval = qMin(tempInterval, 5); if (!mouseWheelHorizontalEventTimer.isActive() || (mouseWheelHorizontalEventTimer.interval() != tempInterval)) { mouseWheelHorizontalEventTimer.start(tempInterval); } } else if (!isActive) { mouseWheelHorizontalEventTimer.stop(); } } else if (!mouseWheelHorizontalEventQueue.isEmpty() && (wheelSpeedX != 0)) { QQueue tempQueue; while (!mouseWheelHorizontalEventQueue.isEmpty()) { buttonslot = mouseWheelHorizontalEventQueue.dequeue(); bool isActive = getActiveSlots().contains(buttonslot); if (isActive && activateEvent) { sendevent(buttonslot, true); sendevent(buttonslot, false); tempQueue.enqueue(buttonslot); } else if (isActive) { tempQueue.enqueue(buttonslot); } } if (!tempQueue.isEmpty()) { mouseWheelHorizontalEventQueue = tempQueue; double distance = getMouseDistanceFromDeadZone(); if (distance > 0.0) { tempInterval = 1000 / wheelSpeedX / distance; } else { tempInterval = 0; } tempInterval = qMin(tempInterval, 5); if (!mouseWheelHorizontalEventTimer.isActive() || (mouseWheelHorizontalEventTimer.interval() != tempInterval)) { mouseWheelHorizontalEventTimer.start(tempInterval); } } else { mouseWheelHorizontalEventTimer.stop(); } } else { mouseWheelHorizontalEventTimer.stop(); } if (activateEvent) { wheelHorizontalTime.restart(); lastWheelHorizontalDistance = getMouseDistanceFromDeadZone(); } } AntiMicroX-antimicrox-b300273/src/joybuttontypes/joygradientbutton.h000066400000000000000000000025031471077622000260070ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYGRADIENTBUTTON_H #define JOYGRADIENTBUTTON_H #include "joybutton.h" class SetJoystick; class JoyGradientButton : public JoyButton { Q_OBJECT public: explicit JoyGradientButton(int sdl_button_index, int originset, SetJoystick *parentSet, QObject *parent); using JoyButton::getPartialName; using JoyButton::setChangeSetCondition; protected slots: virtual void turboEvent(); virtual void wheelEventVertical(); virtual void wheelEventHorizontal(); }; #endif // JOYGRADIENTBUTTON_H AntiMicroX-antimicrox-b300273/src/joybuttontypes/joygyroscopebutton.cpp000066400000000000000000000036031471077622000265610ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joygyroscopebutton.h" #include "joysensordirection.h" JoyGyroscopeButton::JoyGyroscopeButton(JoySensor *sensor, int index, int originset, SetJoystick *parentSet, QObject *parent) : JoySensorButton(sensor, index, originset, parentSet, parent) { } /** * @brief Get translated gyroscope direction name of this button * @returns Translated direction name */ QString JoyGyroscopeButton::getDirectionName() const { QString label = QString(); switch (m_index_sdl) { case JoySensorDirection::SENSOR_UP: label.append(tr("Pitch Up")); break; case JoySensorDirection::SENSOR_DOWN: label.append(tr("Pitch Down")); break; case JoySensorDirection::SENSOR_LEFT: label.append(tr("Yaw Left")); break; case JoySensorDirection::SENSOR_RIGHT: label.append(tr("Yaw Right")); break; case JoySensorDirection::SENSOR_FWD: label.append(tr("Roll Left")); break; case JoySensorDirection::SENSOR_BWD: label.append(tr("Roll Right")); break; default: WARN() << "unknown gyroscope direction"; break; } return label; } AntiMicroX-antimicrox-b300273/src/joybuttontypes/joygyroscopebutton.h000066400000000000000000000021471471077622000262300ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "joybuttontypes/joysensorbutton.h" /** * @brief Represents a gyroscope mapping in a SetJoystick */ class JoyGyroscopeButton : public JoySensorButton { Q_OBJECT public: explicit JoyGyroscopeButton(JoySensor *sensor, int index, int originset, SetJoystick *parentSet, QObject *parent); virtual QString getDirectionName() const override; }; AntiMicroX-antimicrox-b300273/src/joybuttontypes/joysensorbutton.cpp000066400000000000000000000117221471077622000260610ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joysensorbutton.h" #include "event.h" #include "globalvariables.h" #include "joybutton.h" #include "joysensor.h" #include "setjoystick.h" #include "vdpad.h" #include #include JoySensorButton::JoySensorButton(JoySensor *sensor, int index, int originset, SetJoystick *parentSet, QObject *parent) : JoyGradientButton(index, originset, parentSet, parent) , m_sensor(sensor) { // Must be called here since virtual functions calls are disabled in constructors. setMouseCurve(getDefaultMouseCurve()); } /** * @brief Get a 0 indexed number of button * @return 0 indexed button index number */ int JoySensorButton::getRealJoyNumber() const { return m_index_sdl; } /** * @brief Get the name of the button. * Shows the sensor direction name instead of a button number. * @returns Button name */ QString JoySensorButton::getPartialName(bool forceFullFormat, bool displayNames) const { QString temp = m_sensor->getPartialName(forceFullFormat, displayNames); temp.append(": "); if (!buttonName.isEmpty() && displayNames) { if (forceFullFormat) temp.append(tr("Button")).append(" "); temp.append(buttonName); } else if (!defaultButtonName.isEmpty()) { if (forceFullFormat) temp.append(tr("Button")).append(" "); temp.append(defaultButtonName); } else { temp.append(tr("Button")).append(" "); temp.append(getDirectionName()); } return temp; } /** * @brief Get the XML tag name of this button type */ QString JoySensorButton::getXmlName() { return GlobalVariables::JoySensorButton::xmlName; } /** * @brief Get the distance that an element is away from its assigned dead zone * @return Distance away from dead zone */ double JoySensorButton::getDistanceFromDeadZone() { return m_sensor->calculateDirectionalDistance(static_cast(m_index_sdl)); } /** * @brief Get the distance factor that should be used for mouse movement * @return Distance factor that should be used for mouse movement */ double JoySensorButton::getMouseDistanceFromDeadZone() { return m_sensor->calculateDirectionalDistance(static_cast(m_index_sdl)); } void JoySensorButton::setChangeSetCondition(SetChangeCondition condition, bool passive, bool updateActiveString) { Q_UNUSED(updateActiveString); SetChangeCondition oldCondition = setSelectionCondition; if ((condition != setSelectionCondition) && !passive) { if ((condition == SetChangeWhileHeld) || (condition == SetChangeTwoWay)) { // Set new condition emit setAssignmentChanged(static_cast(m_index_sdl), m_sensor->getType(), setSelection, condition); } else if ((setSelectionCondition == SetChangeWhileHeld) || (setSelectionCondition == SetChangeTwoWay)) { // Remove old condition emit setAssignmentChanged(static_cast(m_index_sdl), m_sensor->getType(), setSelection, SetChangeDisabled); } setSelectionCondition = condition; } else if (passive) { setSelectionCondition = condition; } if (setSelectionCondition == SetChangeDisabled) { setChangeSetSelection(-1); } if (setSelectionCondition != oldCondition) { buildActiveZoneSummaryString(); emit propertyUpdated(); } } /** * @brief Check if button should be considered a part of a real controller * axis. Needed for some dialogs so the program won't have to resort to * type checking. * @return Status of being part of a real controller axis */ bool JoySensorButton::isPartRealAxis() { return false; } /** * @brief Returns the default mouse curve for JoySensorButtons. * @returns Default mouse curve */ JoyButton::JoyMouseCurve JoySensorButton::getDefaultMouseCurve() const { return LinearCurve; } /** * @brief Get the JoySensor associated to this button. * @returns JoySensor */ JoySensor *JoySensorButton::getSensor() const { return m_sensor; } /** * @brief returns the direction of this button. */ JoySensorDirection JoySensorButton::getDirection() const { return static_cast(m_index_sdl); } AntiMicroX-antimicrox-b300273/src/joybuttontypes/joysensorbutton.h000066400000000000000000000040311471077622000255210ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "joybuttontypes/joygradientbutton.h" #include "joysensordirection.h" #include "joysensortype.h" #include "logger.h" class SetJoystick; class JoySensor; /** * @brief Represents a sensor mapping in a SetJoystick */ class JoySensorButton : public JoyGradientButton { Q_OBJECT public: explicit JoySensorButton(JoySensor *sensor, int index, int originset, SetJoystick *parentSet, QObject *parent); virtual int getRealJoyNumber() const override; virtual QString getPartialName(bool forceFullFormat = false, bool displayNames = false) const override; virtual QString getXmlName() override; virtual double getDistanceFromDeadZone() override; virtual double getMouseDistanceFromDeadZone() override; virtual void setChangeSetCondition(SetChangeCondition condition, bool passive = false, bool updateActiveString = true) override; virtual bool isPartRealAxis() override; virtual JoyMouseCurve getDefaultMouseCurve() const override; JoySensor *getSensor() const; virtual QString getDirectionName() const = 0; JoySensorDirection getDirection() const; signals: void setAssignmentChanged(JoySensorDirection direction, JoySensorType type, int associated_set, int mode); private: JoySensor *m_sensor; }; AntiMicroX-antimicrox-b300273/src/joycontrolstick.cpp000066400000000000000000003647251471077622000227260ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joycontrolstick.h" #include "globalvariables.h" #include "inputdevice.h" #include "joyaxis.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joybuttontypes/joycontrolstickmodifierbutton.h" #include "xml/joybuttonxml.h" #include #include #include #include #include #include #include //#include #include const JoyControlStick::JoyMode JoyControlStick::DEFAULTMODE = JoyControlStick::StandardMode; JoyControlStick::JoyControlStick(JoyAxis *axis1, JoyAxis *axis2, int index, int originset, QObject *parent) : QObject(parent) { this->axisX = axis1; this->axisX->setControlStick(this); this->axisY = axis2; this->axisY->setControlStick(this); this->index = index; this->originset = originset; this->modifierButton = nullptr; reset(); populateStickBtns(); directionDelayTimer.setSingleShot(true); connect(&directionDelayTimer, &QTimer::timeout, this, &JoyControlStick::stickDirectionChangeEvent); } JoyControlStick::~JoyControlStick() { if (!axisX.isNull()) axisX->removeControlStick(false); if (!axisY.isNull()) axisY->removeControlStick(false); } /** * @brief Take the input value for the two axes that make up a stick and * activate the proper event based on the current values. * @param Should set changing routines be ignored. */ void JoyControlStick::joyEvent(bool ignoresets) { safezone = !inDeadZone(); if (safezone && !isActive) { isActive = true; emit active(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); if (ignoresets || (stickDelay == 0)) { if (directionDelayTimer.isActive()) directionDelayTimer.stop(); createDeskEvent(ignoresets); } else { if (!directionDelayTimer.isActive()) directionDelayTimer.start(stickDelay); } } else if (!safezone && isActive) { isActive = false; emit released(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); if (ignoresets || (stickDelay == 0)) { if (directionDelayTimer.isActive()) directionDelayTimer.stop(); createDeskEvent(ignoresets); } else { if (!directionDelayTimer.isActive()) directionDelayTimer.start(stickDelay); } } else if (isActive) { if (ignoresets || (stickDelay == 0)) { if (directionDelayTimer.isActive()) directionDelayTimer.stop(); createDeskEvent(ignoresets); } else { JoyStickDirections pendingDirection = calculateStickDirection(); if (currentDirection != pendingDirection) { if (!directionDelayTimer.isActive()) directionDelayTimer.start(stickDelay); } else { if (directionDelayTimer.isActive()) directionDelayTimer.stop(); createDeskEvent(ignoresets); } } } emit moved(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); pendingStickEvent = false; } /** * @brief Check the current stick position to see if it lies in * the assigned dead zone. * @return If stick position is in the assigned dead zone */ bool JoyControlStick::inDeadZone() { int axis1Value = axisX->getCurrentRawValue(); int axis2Value = axisY->getCurrentRawValue(); int squareDist = (axis1Value * axis1Value) + (axis2Value * axis2Value); return squareDist <= (deadZone * deadZone); } /** * @brief Populate the virtual buttons assigned to an analog stick. */ void JoyControlStick::populateButtons() { populateStickBtns(); } void JoyControlStick::populateStickBtns() { JoyControlStickButton *button = new JoyControlStickButton(this, StickUp, originset, getParentSet(), this); buttons.insert(StickUp, button); button = new JoyControlStickButton(this, StickDown, originset, getParentSet(), this); buttons.insert(StickDown, button); button = new JoyControlStickButton(this, StickLeft, originset, getParentSet(), this); buttons.insert(StickLeft, button); button = new JoyControlStickButton(this, StickRight, originset, getParentSet(), this); buttons.insert(StickRight, button); button = new JoyControlStickButton(this, StickLeftUp, originset, getParentSet(), this); buttons.insert(StickLeftUp, button); button = new JoyControlStickButton(this, StickLeftDown, originset, getParentSet(), this); buttons.insert(StickLeftDown, button); button = new JoyControlStickButton(this, StickRightDown, originset, getParentSet(), this); buttons.insert(StickRightDown, button); button = new JoyControlStickButton(this, StickRightUp, originset, getParentSet(), this); buttons.insert(StickRightUp, button); modifierButton = new JoyControlStickModifierButton(this, originset, getParentSet(), this); } /** * @brief Get the assigned dead zone value. * @return Assigned dead zone value */ int JoyControlStick::getDeadZone() { return deadZone; } /** * @brief Get the assigned diagonal range value. * @return Assigned diagonal range. */ int JoyControlStick::getDiagonalRange() { return diagonalRange; } /** * @brief Find the position of the two stick axes, deactivate no longer used * stick direction button and then activate direction buttons for new * direction. * @param Should set changing operations be ignored. Necessary in the middle * of a set change. */ void JoyControlStick::createDeskEvent(bool ignoresets) { JoyControlStickButton *eventbutton1 = nullptr; JoyControlStickButton *eventbutton2 = nullptr; JoyControlStickButton *eventbutton3 = nullptr; if (safezone) { switch (currentMode) { case StandardMode: determineStandardModeEvent(eventbutton1, eventbutton2); break; case EightWayMode: determineEightWayModeEvent(eventbutton1, eventbutton2, eventbutton3); break; case FourWayCardinal: determineFourWayCardinalEvent(eventbutton1, eventbutton2); break; case FourWayDiagonal: determineFourWayDiagonalEvent(eventbutton3); break; } } else { currentDirection = StickCentered; } /* * Release any currently active stick buttons. */ if ((eventbutton1 == nullptr) && (activeButton1 != nullptr)) { // Currently in deadzone. Disable currently active button. performButtonRelease(activeButton1, ignoresets); } else if ((eventbutton1 != nullptr) && (activeButton1 != nullptr) && (eventbutton1 != activeButton1)) { // Deadzone skipped. Button for new event is not the currently // active button. Disable the active button. performButtonRelease(activeButton1, ignoresets); } if ((eventbutton2 == nullptr) && (activeButton2 != nullptr)) { // Currently in deadzone. Disable currently active button. performButtonRelease(activeButton2, ignoresets); } else if ((eventbutton2 != nullptr) && (activeButton2 != nullptr) && (eventbutton2 != activeButton2)) { // Deadzone skipped. Button for new event is not the currently // active button. Disable the active button. performButtonRelease(activeButton2, ignoresets); } if ((eventbutton3 == nullptr) && (activeButton3 != nullptr)) { // Currently in deadzone. Disable currently active button. performButtonRelease(activeButton3, ignoresets); } else if ((eventbutton3 != nullptr) && (activeButton3 != nullptr) && (eventbutton3 != activeButton3)) { // Deadzone skipped. Button for new event is not the currently // active button. Disable the active button. performButtonRelease(activeButton3, ignoresets); } // Activate modifier button before activating directional buttons. // Value from the new stick event will be used to determine // distance events. // Release modifier button after releasing directional buttons. double distance = getAbsoluteRawDistance(); if (m_modifier_zone_inverted) { if (safezone && distance < m_modifier_zone) modifierButton->joyEvent(true, ignoresets); else modifierButton->joyEvent(false, ignoresets); } else { if (safezone && distance > m_modifier_zone) modifierButton->joyEvent(true, ignoresets); else modifierButton->joyEvent(false, ignoresets); } /* * Enable stick buttons. */ if ((eventbutton1 != nullptr) && (activeButton1 == nullptr)) { // There is no active button. Call joyEvent and set current // button as active button performButtonPress(eventbutton1, activeButton1, ignoresets); } else if ((eventbutton1 != nullptr) && (activeButton1 != nullptr) && (eventbutton1 == activeButton1)) { // Button is currently active. Just pass current value performButtonPress(eventbutton1, activeButton1, ignoresets); } if ((eventbutton2 != nullptr) && (activeButton2 == nullptr)) { // There is no active button. Call joyEvent and set current // button as active button performButtonPress(eventbutton2, activeButton2, ignoresets); } else if ((eventbutton2 != nullptr) && (activeButton2 != nullptr) && (eventbutton2 == activeButton2)) { // Button is currently active. Just pass current value performButtonPress(eventbutton2, activeButton2, ignoresets); } if ((eventbutton3 != nullptr) && (activeButton3 == nullptr)) { // There is no active button. Call joyEvent and set current // button as active button performButtonPress(eventbutton3, activeButton3, ignoresets); } else if ((eventbutton3 != nullptr) && (activeButton3 != nullptr) && (eventbutton3 == activeButton3)) { // Button is currently active. Just pass current value performButtonPress(eventbutton3, activeButton3, ignoresets); } } /** * @brief Calculate the bearing (in degrees) corresponding to the current * position of the X and Y axes of a stick. * @return Bearing (in degrees) */ double JoyControlStick::calculateBearing() { return calculateBearing(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } /** * @brief Calculate the bearing (in degrees) corresponding to the * passed X and Y axes values associated with the stick. * @param X axis value * @param Y axis value * @return Bearing (in degrees) */ double JoyControlStick::calculateBearing(int axisXValue, int axisYValue) { double finalAngle = 0.0; int axis1Value = axisXValue; int axis2Value = axisYValue; if ((axis1Value == 0) && (axis2Value == 0)) { finalAngle = 0.0; } else { double temp1 = axis1Value; double temp2 = axis2Value; double angle = (atan2(temp1, -temp2) * 180) / GlobalVariables::JoyControlStick::PI; if ((axis1Value >= 0) && (axis2Value <= 0)) { // NE Quadrant finalAngle = angle; } else if ((axis1Value >= 0) && (axis2Value >= 0)) { // SE Quadrant (angle will be positive) finalAngle = angle; } else if ((axis1Value <= 0) && (axis2Value >= 0)) { // SW Quadrant (angle will be negative) finalAngle = 360.0 + angle; } else if ((axis1Value <= 0) && (axis2Value <= 0)) { // NW Quadrant (angle will be negative) finalAngle = 360.0 + angle; } } return finalAngle; } /** * @brief Get current radial distance of the stick position past the assigned * dead zone. * @return Distance percentage in the range of 0.0 - 1.0. */ double JoyControlStick::getDistanceFromDeadZone() { return getDistanceFromDeadZone(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } /** * @brief Get radial distance of the stick position past the assigned dead zone * based on the passed X and Y axes values associated with the stick. * @param X axis value * @param Y axis value * @return Distance percentage in the range of 0.0 - 1.0. */ double JoyControlStick::getDistanceFromDeadZone(int axisXValue, int axisYValue) { double distance = 0.0; int axis1Value = axisXValue; int axis2Value = axisYValue; double angle2 = atan2(axis1Value, -axis2Value); double ang_sin = sin(angle2); double ang_cos = cos(angle2); int squared_dist = (axis1Value * axis1Value) + (axis2Value * axis2Value); int dist = sqrt(squared_dist); double squareStickFullPhi = qMin((ang_sin != 0.0) ? 1 / fabs(ang_sin) : 2, ang_cos != 0.0 ? 1 / fabs(ang_cos) : 2); double circle = this->circle; double circleStickFull = (squareStickFullPhi - 1) * circle + 1; double adjustedDist = (circleStickFull > 1.0) ? (dist / circleStickFull) : dist; double adjustedDeadZone = (circleStickFull > 1.0) ? (deadZone / circleStickFull) : deadZone; distance = (adjustedDist - adjustedDeadZone) / (static_cast(maxZone) - adjustedDeadZone); distance = qBound(0.0, distance, 1.0); return distance; } /** * @brief Get distance of the Y axis past the assigned dead zone. * @param Should interpolation be performed along the diagonal regions. * @return Distance percentage in the range of 0.0 - 1.0. */ double JoyControlStick::calculateYDistanceFromDeadZone(bool interpolate) { return calculateYDistanceFromDeadZone(axisX->getCurrentRawValue(), axisY->getCurrentRawValue(), interpolate); } /** * @brief Get distance of the Y axis past the assigned dead zone based * on the passed X and Y axis values for the analog stick. * @param X axis value * @param Y axis value * @param Should interpolation be performed along the diagonal regions. * @return Distance percentage in the range of 0.0 - 1.0. */ double JoyControlStick::calculateYDistanceFromDeadZone(int axisXValue, int axisYValue, bool interpolate) { double distance = 0.0; int axis1Value = axisXValue; int axis2Value = axisYValue; double angle2 = atan2(axis1Value, -axis2Value); double ang_sin = sin(angle2); double ang_cos = cos(angle2); int deadY = abs(floor(deadZone * ang_cos + 0.5)); double squareStickFullPhi = qMin(ang_sin != 0.0 ? 1 / fabs(ang_sin) : 2, ang_cos != 0.0 ? 1 / fabs(ang_cos) : 2); double circle = this->circle; double circleStickFull = (squareStickFullPhi - 1) * circle + 1; double adjustedAxis2Value = (circleStickFull > 1.0) ? (axis2Value / circleStickFull) : axis2Value; double adjustedDeadYZone = (circleStickFull > 1.0) ? (deadY / circleStickFull) : deadY; // Interpolation would return the correct value if diagonalRange is 90 but // the routine gets skipped to save time. if (interpolate && (diagonalRange < 90)) { JoyStickDirections direction = calculateStickDirection(axis1Value, axis2Value); if ((direction == StickRightUp) || (direction == StickUp)) { QList tempangles = getDiagonalZoneAngles(); double minangle = tempangles.at(1); double square_dist = getAbsoluteRawDistance(axis1Value, axis2Value); double mindeadY = fabs(square_dist * sin(minangle * GlobalVariables::JoyControlStick::PI / 180.0)); double currentDeadY = qMax(adjustedDeadYZone, mindeadY); double maxRange = static_cast(maxZone) - currentDeadY; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis2Value) - currentDeadY) / maxRange; distance = tempdist4; } else if ((direction == StickRightDown) || (direction == StickRight)) { QList tempfuck = getDiagonalZoneAngles(); double minangle = tempfuck.at(4); double square_dist = getAbsoluteRawDistance(axis1Value, axis2Value); double mindeadY = fabs(square_dist * sin((minangle - 90.0) * GlobalVariables::JoyControlStick::PI / 180.0)); double currentDeadY = qMax(adjustedDeadYZone, mindeadY); double maxRange = static_cast(maxZone) - currentDeadY; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis2Value) - currentDeadY) / maxRange; distance = tempdist4; } else if ((direction == StickLeftDown) || (direction == StickDown)) { QList tempangles = getDiagonalZoneAngles(); double minangle = tempangles.at(6); double square_dist = getAbsoluteRawDistance(axis1Value, axis2Value); double mindeadY = fabs(square_dist * sin((minangle - 180.0) * GlobalVariables::JoyControlStick::PI / 180.0)); double currentDeadY = qMax(adjustedDeadYZone, mindeadY); double maxRange = static_cast(maxZone) - currentDeadY; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis2Value) - currentDeadY) / maxRange; distance = tempdist4; } else if ((direction == StickLeftUp) || (direction == StickLeft)) { QList tempangles = getDiagonalZoneAngles(); double minangle = tempangles.at(8); double square_dist = getAbsoluteRawDistance(axis1Value, axis2Value); double mindeadY = fabs(square_dist * sin((minangle - 270.0) * GlobalVariables::JoyControlStick::PI / 180.0)); double currentDeadY = qMax(adjustedDeadYZone, mindeadY); double maxRange = static_cast(maxZone) - currentDeadY; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis2Value) - currentDeadY) / maxRange; distance = tempdist4; } else { // Backup plan. Should not arrive here. double maxRange = static_cast(maxZone) - adjustedDeadYZone; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis2Value) - adjustedDeadYZone) / maxRange; distance = tempdist4; } } else { // No interpolation desired or diagonal range is 90 degrees. double maxRange = static_cast(maxZone) - adjustedDeadYZone; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis2Value) - adjustedDeadYZone) / maxRange; distance = tempdist4; } distance = qBound(0.0, distance, 1.0); return distance; } /** * @brief Get distance of the X axis past the assigned dead zone. * @param Should interpolation be performed along the diagonal regions. * @return Distance percentage in the range of 0.0 - 1.0. */ double JoyControlStick::calculateXDistanceFromDeadZone(bool interpolate) { return calculateXDistanceFromDeadZone(axisX->getCurrentRawValue(), axisY->getCurrentRawValue(), interpolate); } /** * @brief Get distance of the X axis past the assigned dead zone based * on the passed X and Y axis values for the analog stick. * @param X axis value * @param Y axis value * @param Should interpolation be performed along the diagonal regions. * @return Distance percentage in the range of 0.0 - 1.0. */ double JoyControlStick::calculateXDistanceFromDeadZone(int axisXValue, int axisYValue, bool interpolate) { double distance = 0.0; int axis1Value = axisXValue; int axis2Value = axisYValue; double angle2 = atan2(axis1Value, -axis2Value); double ang_sin = sin(angle2); double ang_cos = cos(angle2); int deadX = abs(floor(deadZone * ang_sin + 0.5)); double squareStickFullPhi = qMin(ang_sin != 0.0 ? 1 / fabs(ang_sin) : 2, ang_cos != 0.0 ? 1 / fabs(ang_cos) : 2); double circle = this->circle; double circleStickFull = (squareStickFullPhi - 1) * circle + 1; double adjustedAxis1Value = (circleStickFull > 1.0) ? (axis1Value / circleStickFull) : axis1Value; double adjustedDeadXZone = (circleStickFull > 1.0) ? (deadX / circleStickFull) : deadX; // Interpolation would return the correct value if diagonalRange is 90 but // the routine gets skipped to save time. if (interpolate && (diagonalRange < 90)) { JoyStickDirections direction = calculateStickDirection(axis1Value, axis2Value); if ((direction == StickRightUp) || (direction == StickRight)) { QList tempangles = getDiagonalZoneAngles(); double maxangle = tempangles.at(3); double square_dist = getAbsoluteRawDistance(axis1Value, axis2Value); double mindeadX = fabs(square_dist * cos(maxangle * GlobalVariables::JoyControlStick::PI / 180.0)); double currentDeadX = qMax(mindeadX, adjustedDeadXZone); double maxRange = static_cast(maxZone) - currentDeadX; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis1Value) - currentDeadX) / maxRange; distance = tempdist4; } else if ((direction == StickRightDown) || (direction == StickDown)) { QList tempangles = getDiagonalZoneAngles(); double maxangle = tempangles.at(5); double square_dist = getAbsoluteRawDistance(axis1Value, axis2Value); double mindeadX = fabs(square_dist * cos((maxangle - 90.0) * GlobalVariables::JoyControlStick::PI / 180.0)); double currentDeadX = qMax(mindeadX, adjustedDeadXZone); double maxRange = static_cast(maxZone) - currentDeadX; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis1Value) - currentDeadX) / maxRange; distance = tempdist4; } else if ((direction == StickLeftDown) || (direction == StickLeft)) { QList tempangles = getDiagonalZoneAngles(); double maxangle = tempangles.at(7); double square_dist = getAbsoluteRawDistance(axis1Value, axis2Value); double mindeadX = fabs(square_dist * cos((maxangle - 180.0) * GlobalVariables::JoyControlStick::PI / 180.0)); double currentDeadX = qMax(mindeadX, adjustedDeadXZone); double maxRange = static_cast(maxZone) - currentDeadX; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis1Value) - currentDeadX) / maxRange; distance = tempdist4; } else if ((direction == StickLeftUp) || (direction == StickUp)) { QList tempangles = getDiagonalZoneAngles(); double maxangle = tempangles.at(1); double square_dist = getAbsoluteRawDistance(axis1Value, axis2Value); double mindeadX = fabs(square_dist * cos((maxangle - 270.0) * GlobalVariables::JoyControlStick::PI / 180.0)); double currentDeadX = qMax(mindeadX, adjustedDeadXZone); double maxRange = static_cast(maxZone) - currentDeadX; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis1Value) - currentDeadX) / maxRange; distance = tempdist4; } else { // Backup plan. Should not arrive here. double maxRange = static_cast(maxZone) - adjustedDeadXZone; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis1Value) - adjustedDeadXZone) / maxRange; distance = tempdist4; } } else { // No interpolation desired or diagonal range is 90 degrees. double maxRange = static_cast(maxZone) - adjustedDeadXZone; double tempdist4 = 0.0; if (maxRange != 0.0) tempdist4 = (fabs(adjustedAxis1Value) - adjustedDeadXZone) / maxRange; distance = tempdist4; } distance = qBound(0.0, distance, 1.0); return distance; } /** * @brief Get the raw radial distance of the stick. Values will be between 0 - 32,767. * @return Radial distance in the range of 0 - 32,767. */ double JoyControlStick::getAbsoluteRawDistance() { double temp = getAbsoluteRawDistance(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); return temp; } double JoyControlStick::getAbsoluteRawDistance(int axisXValue, int axisYValue) { int axis1Value = axisXValue; int axis2Value = axisYValue; int square_dist = (axis1Value * axis1Value) + (axis2Value * axis2Value); return sqrt(square_dist); } double JoyControlStick::getNormalizedAbsoluteDistance() { int axis1Value = axisX->getCurrentRawValue(); int axis2Value = axisY->getCurrentRawValue(); int square_dist = (axis1Value * axis1Value) + (axis2Value * axis2Value); double distance = sqrt(square_dist) / static_cast(maxZone); if (distance > 1.0) distance = 1.0; else if (distance < 0.0) distance = 0.0; return distance; } double JoyControlStick::getRadialDistance(int axisXValue, int axisYValue) { int axis1Value = axisXValue; int axis2Value = axisYValue; int square_dist = (axis1Value * axis1Value) + (axis2Value * axis2Value); double distance = sqrt(square_dist) / static_cast(maxZone); if (distance > 1.0) distance = 1.0; else if (distance < 0.0) distance = 0.0; return distance; } void JoyControlStick::setIndex(int index) { this->index = index; } int JoyControlStick::getIndex() { return index; } int JoyControlStick::getRealJoyIndex() { return index + 1; } QString JoyControlStick::getName(bool forceFullFormat, bool displayNames) { QString label = getPartialName(forceFullFormat, displayNames); label.append(": "); QStringList tempList = QStringList(); if (buttons.contains(StickUp)) { JoyControlStickButton *button = buttons.value(StickUp); if (!button->getButtonName().isEmpty()) tempList.append(button->getButtonName()); else tempList.append(button->getSlotsSummary()); } if (buttons.contains(StickLeft)) { JoyControlStickButton *button = buttons.value(StickLeft); if (!button->getButtonName().isEmpty()) tempList.append(button->getButtonName()); else tempList.append(button->getSlotsSummary()); } if (buttons.contains(StickDown)) { JoyControlStickButton *button = buttons.value(StickDown); if (!button->getButtonName().isEmpty()) tempList.append(button->getButtonName()); else tempList.append(button->getSlotsSummary()); } if (buttons.contains(StickRight)) { JoyControlStickButton *button = buttons.value(StickRight); if (!button->getButtonName().isEmpty()) tempList.append(button->getButtonName()); else tempList.append(button->getSlotsSummary()); } label.append(tempList.join(", ")); return label; } QString JoyControlStick::getPartialName(bool forceFullFormat, bool displayNames) { QString label = QString(); if (!stickName.isEmpty() && displayNames) { if (forceFullFormat) label.append(tr("Stick")).append(" "); label.append(stickName); } else if (!defaultStickName.isEmpty()) { if (forceFullFormat) label.append(tr("Stick")).append(" "); label.append(defaultStickName); } else { label.append(tr("Stick")).append(" "); label.append(QString::number(getRealJoyIndex())); } setStickName(label); return label; } void JoyControlStick::setDefaultStickName(QString tempname) { defaultStickName = tempname; emit stickNameChanged(); } QString JoyControlStick::getDefaultStickName() { return defaultStickName; } int JoyControlStick::getMaxZone() { return maxZone; } /** * @brief Returns the modifier zone of the stick */ int JoyControlStick::getModifierZone() const { return m_modifier_zone; } /** * @brief Checks if the modifier zone of this stick is inverted * @returns True if the modifier zone is inverted, false otherwise */ bool JoyControlStick::getModifierZoneInverted() const { return m_modifier_zone_inverted; } int JoyControlStick::getCurrentlyAssignedSet() { return originset; } void JoyControlStick::reset() { deadZone = GlobalVariables::JoyControlStick::DEFAULTDEADZONE; maxZone = GlobalVariables::JoyAxis::AXISMAXZONE; m_modifier_zone = GlobalVariables::JoyControlStick::DEFAULTMODIFIERZONE; m_modifier_zone_inverted = GlobalVariables::JoyControlStick::DEFAULTMODIFIERZONEINVERTED; diagonalRange = GlobalVariables::JoyControlStick::DEFAULTDIAGONALRANGE; isActive = false; pendingStickEvent = false; activeButton1 = nullptr; activeButton2 = nullptr; activeButton3 = nullptr; safezone = false; currentDirection = StickCentered; currentMode = StandardMode; stickName.clear(); circle = GlobalVariables::JoyControlStick::DEFAULTCIRCLE; stickDelay = GlobalVariables::JoyControlStick::DEFAULTSTICKDELAY; resetButtons(); } void JoyControlStick::setDeadZone(int value) { value = std::min(abs(value), GlobalVariables::JoyAxis::AXISMAX); if ((value != deadZone) && (value <= maxZone)) { deadZone = value; emit deadZoneChanged(value); emit propertyUpdated(); } } void JoyControlStick::setMaxZone(int value) { value = std::min(abs(value), GlobalVariables::JoyAxis::AXISMAX); if ((value != maxZone) && (value > deadZone)) { maxZone = value; emit maxZoneChanged(value); emit propertyUpdated(); } } /** * @brief Sets the modifier zone of the stick to the given value * @param[in] value New stick modifier zone */ void JoyControlStick::setModifierZone(int value) { value = std::min(abs(value), GlobalVariables::JoyAxis::AXISMAX); if ((value != m_modifier_zone) && (value < maxZone) && (value > deadZone)) { m_modifier_zone = value; emit modifierZoneChanged(value); emit propertyUpdated(); } } /** * @brief Inverts the direction of the modifier zone of the stick. * @param[in] value True if the zone should be inverted, false otherwise. */ void JoyControlStick::setModifierZoneInverted(bool value) { if (value != m_modifier_zone_inverted) { m_modifier_zone_inverted = value; emit modifierZoneChanged(m_modifier_zone); emit propertyUpdated(); } } /** * @brief Check if the stick is calibrated * @returns True if both axes of the stick are calibrated, false otherwise. */ bool JoyControlStick::isCalibrated() const { return axisX->isCalibrated() && axisY->isCalibrated(); } /** * @brief Resets the calibration of both stick axes back to uncalibrated state. */ void JoyControlStick::resetCalibration() { axisX->resetCalibration(); axisY->resetCalibration(); } /** * @brief Reads the calibration values of both stick axes * @param[out] offsetX Offset value "a" for X axis * @param[out] gainX Gain value "b" for X axis * @param[out] offsetY Offset value "a" for Y axis * @param[out] gainY Gain value "b" for Y axis */ void JoyControlStick::getCalibration(double *offsetX, double *gainX, double *offsetY, double *gainY) const { axisX->getCalibration(offsetX, gainX); axisY->getCalibration(offsetY, gainY); } /** * @brief Sets the axis calibration values and sets the calibration flag. * Calibrated value is calculated by the formula "a+b*x". * @param[in] offsetX Offset value "a" for X axis * @param[in] gainX Gain value "b" for X axis * @param[in] offsetY Offset value "a" for Y axis * @param[in] gainY Gain value "b" for Y axis */ void JoyControlStick::setCalibration(double offsetX, double gainX, double offsetY, double gainY) { axisX->setCalibration(offsetX, gainX); axisY->setCalibration(offsetY, gainY); } /** * @brief Set the diagonal range value for a stick. * @param Value between 1 - 90. */ void JoyControlStick::setDiagonalRange(int value) { if (value < 1) value = 1; else if (value > 90) value = 90; if (value != diagonalRange) { diagonalRange = value; emit diagonalRangeChanged(value); emit propertyUpdated(); } } /** * @brief Take a XML stream and set the stick and direction button properties * according to the values contained within the stream. * @param QXmlStreamReader instance that will be used to read property values. */ void JoyControlStick::readConfig(QXmlStreamReader *xml) { if (xml->isStartElement() && (xml->name().toString() == "stick")) { xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != "stick"))) { if ((xml->name().toString() == "deadZone") && xml->isStartElement()) { QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); this->setDeadZone(tempchoice); } else if ((xml->name().toString() == "maxZone") && xml->isStartElement()) { QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); this->setMaxZone(tempchoice); } else if ((xml->name().toString() == "modifierZone") && xml->isStartElement()) { QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); setModifierZone(tempchoice); } else if ((xml->name().toString() == "modifierZoneInverted") && xml->isStartElement()) { QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); setModifierZoneInverted(tempchoice); } else if ((xml->name().toString() == "diagonalRange") && xml->isStartElement()) { QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); this->setDiagonalRange(tempchoice); } else if ((xml->name().toString() == "mode") && xml->isStartElement()) { QString temptext = xml->readElementText(); if (temptext == "eight-way") { this->setJoyMode(EightWayMode); } else if (temptext == "four-way") { this->setJoyMode(FourWayCardinal); } else if (temptext == "diagonal") { this->setJoyMode(FourWayDiagonal); } } else if ((xml->name().toString() == "squareStick") && xml->isStartElement()) { int tempchoice = xml->readElementText().toInt(); if ((tempchoice > 0) && (tempchoice <= 100)) this->setCircleAdjust(tempchoice / 100.0); } else if ((xml->name().toString() == GlobalVariables::JoyControlStickButton::xmlName) && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); JoyControlStickButton *button = buttons.value(static_cast(index)); QPointer joyButtonXml = new JoyButtonXml(button); if (button != nullptr) joyButtonXml->readConfig(xml); else xml->skipCurrentElement(); if (!joyButtonXml.isNull()) delete joyButtonXml; } else if ((xml->name().toString() == GlobalVariables::JoyControlStickModifierButton::xmlName) && xml->isStartElement()) { JoyButtonXml *joyButtonXml = new JoyButtonXml(modifierButton); joyButtonXml->readConfig(xml); } else if ((xml->name().toString() == "stickDelay") && xml->isStartElement()) { QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); this->setStickDelay(tempchoice); } else { xml->skipCurrentElement(); } xml->readNextStartElement(); } } } /** * @brief Write the status of the properties of a stick and direction buttons * to an XML stream. * @param QXmlStreamWriter instance that will be used to write a profile. */ void JoyControlStick::writeConfig(QXmlStreamWriter *xml) { if (!isDefault()) { xml->writeStartElement("stick"); xml->writeAttribute("index", QString::number(index + 1)); if (deadZone != GlobalVariables::JoyControlStick::DEFAULTDEADZONE) xml->writeTextElement("deadZone", QString::number(deadZone)); if (maxZone != GlobalVariables::JoyControlStick::DEFAULTMAXZONE) xml->writeTextElement("maxZone", QString::number(maxZone)); if (m_modifier_zone != GlobalVariables::JoyControlStick::DEFAULTMODIFIERZONE) xml->writeTextElement("modifierZone", QString::number(m_modifier_zone)); if (m_modifier_zone_inverted != GlobalVariables::JoyControlStick::DEFAULTMODIFIERZONEINVERTED) xml->writeTextElement("modifierZoneInverted", QString::number(m_modifier_zone_inverted)); if ((currentMode == StandardMode || currentMode == EightWayMode) && (diagonalRange != GlobalVariables::JoyControlStick::DEFAULTDIAGONALRANGE)) { xml->writeTextElement("diagonalRange", QString::number(diagonalRange)); } switch (currentMode) { case EightWayMode: xml->writeTextElement("mode", "eight-way"); break; case FourWayCardinal: xml->writeTextElement("mode", "four-way"); break; case FourWayDiagonal: xml->writeTextElement("mode", "diagonal"); break; default: break; } if (circle > GlobalVariables::JoyControlStick::DEFAULTCIRCLE) xml->writeTextElement("squareStick", QString::number(circle * 100)); if (stickDelay > GlobalVariables::JoyControlStick::DEFAULTSTICKDELAY) xml->writeTextElement("stickDelay", QString::number(stickDelay)); QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); JoyButtonXml *joyButtonXml = new JoyButtonXml(button); joyButtonXml->writeConfig(xml); delete joyButtonXml; joyButtonXml = nullptr; } if (!modifierButton->isDefault()) { JoyButtonXml *joyButtonXmlModif = new JoyButtonXml(modifierButton); joyButtonXmlModif->writeConfig(xml); } xml->writeEndElement(); } } /** * @brief Reset all the properties of the stick direction buttons and the * stick modifier button. */ void JoyControlStick::resetButtons() { QHashIterator iter(buttons); while (iter.hasNext()) { JoyButton *button = iter.next().value(); if (button != nullptr) button->reset(); } if (modifierButton != nullptr) modifierButton->reset(); } /** * @brief Get a pointer to the stick direction button for the desired * direction. * @param Value of the direction of the stick. * @return Pointer to the stick direction button for the stick * direction. */ JoyControlStickButton *JoyControlStick::getDirectionButton(JoyStickDirections direction) { JoyControlStickButton *button = buttons.value(direction); return button; } /** * @brief Used to calculate the distance value that should be used for mouse * movement. * @param button * @return Distance factor that should be used for mouse movement */ double JoyControlStick::calculateMouseDirectionalDistance(JoyControlStickButton *button) { double finalDistance = 0.0; switch (currentDirection) { case StickUp: { finalDistance = calculateYDistanceFromDeadZone(true); break; } case StickRightUp: { if ((activeButton1 != nullptr) && (activeButton1 == button)) { finalDistance = calculateXDistanceFromDeadZone(true); } else if ((activeButton2 != nullptr) && (activeButton2 == button)) { finalDistance = calculateYDistanceFromDeadZone(true); } else if ((activeButton3 != nullptr) && (activeButton3 == button)) { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(); } break; } case StickRight: { finalDistance = calculateXDistanceFromDeadZone(true); break; } case StickRightDown: { if ((activeButton1 != nullptr) && (activeButton1 == button)) { finalDistance = calculateXDistanceFromDeadZone(true); } else if ((activeButton2 != nullptr) && (activeButton2 == button)) { finalDistance = calculateYDistanceFromDeadZone(true); } else if ((activeButton3 != nullptr) && (activeButton3 == button)) { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(); } break; } case StickDown: { finalDistance = calculateYDistanceFromDeadZone(true); break; } case StickLeftDown: { if ((activeButton1 != nullptr) && (activeButton1 == button)) { finalDistance = calculateXDistanceFromDeadZone(true); } else if ((activeButton2 != nullptr) && (activeButton2 == button)) { finalDistance = calculateYDistanceFromDeadZone(true); } else if ((activeButton3 != nullptr) && (activeButton3 == button)) { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(); } break; } case StickLeft: { finalDistance = calculateXDistanceFromDeadZone(true); break; } case StickLeftUp: { if ((activeButton1 != nullptr) && (activeButton1 == button)) { finalDistance = calculateXDistanceFromDeadZone(true); } else if ((activeButton2 != nullptr) && (activeButton2 == button)) { finalDistance = calculateYDistanceFromDeadZone(true); } else if ((activeButton3 != nullptr) && (activeButton3 == button)) { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(); } break; } default: break; } return finalDistance; } double JoyControlStick::calculateLastMouseDirectionalDistance(JoyControlStickButton *button) { double finalDistance = 0.0; JoyStickDirections direction = calculateStickDirection(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); if ((direction == StickUp) && (button->getJoyNumber() == static_cast(StickUp))) { if (axisY->getLastKnownThrottleValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateYDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (direction == StickRightUp) { if (button->getJoyNumber() == static_cast(StickRight)) { if (axisX->getLastKnownThrottleValue() < 0) { finalDistance = 0.0; } else { finalDistance = calculateXDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (button->getJoyNumber() == static_cast(StickUp)) { if (axisY->getLastKnownThrottleValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateYDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (button->getJoyNumber() == static_cast(StickRightUp)) { if ((axisX->getLastKnownThrottleValue() <= 0) || (axisY->getLastKnownThrottleValue() >= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } } } else if ((direction == StickRight) && (button->getJoyNumber() == static_cast(StickRight))) { if (axisX->getLastKnownThrottleValue() < 0) { finalDistance = 0.0; } else { finalDistance = calculateXDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (direction == StickRightDown) { if (button->getJoyNumber() == static_cast(StickRight)) { if (axisX->getLastKnownThrottleValue() < 0) { finalDistance = 0.0; } else { finalDistance = calculateXDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (button->getJoyNumber() == static_cast(StickDown)) { if (axisY->getLastKnownThrottleValue() < 0) { finalDistance = 0.0; } else { finalDistance = calculateYDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (button->getJoyNumber() == static_cast(StickRightDown)) { if ((axisX->getLastKnownThrottleValue() <= 0) || (axisY->getLastKnownThrottleValue() >= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } } } else if (direction == StickDown && (button->getJoyNumber() == static_cast(StickDown))) { if (axisY->getLastKnownThrottleValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateYDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (direction == StickLeftDown) { if (button->getJoyNumber() == static_cast(StickLeft)) { if (axisX->getLastKnownThrottleValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateXDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (button->getJoyNumber() == static_cast(StickDown)) { if (axisY->getLastKnownThrottleValue() < 0) { finalDistance = 0.0; } else { finalDistance = calculateYDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (button->getJoyNumber() == static_cast(StickLeftDown)) { if ((axisX->getLastKnownThrottleValue() >= 0) || (axisY->getLastKnownThrottleValue() <= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } } } else if ((direction == StickLeft) && (button->getJoyNumber() == static_cast(StickLeft))) { if (axisX->getLastKnownThrottleValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateXDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (direction == StickLeftUp) { if (button->getJoyNumber() == static_cast(StickLeft)) { if (axisX->getLastKnownThrottleValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateXDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (button->getJoyNumber() == static_cast(StickUp)) { if (axisY->getLastKnownThrottleValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateYDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue(), true); } } else if (button->getJoyNumber() == static_cast(StickLeftUp)) { if ((axisX->getLastKnownThrottleValue() >= 0) || (axisY->getLastKnownThrottleValue() >= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } } } return finalDistance; } double JoyControlStick::calculateLastDirectionalDistance() { double finalDistance = 0.0; JoyStickDirections direction = calculateStickDirection(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); switch (direction) { case StickUp: { if (!(axisX->getLastKnownThrottleValue() >= 0)) { finalDistance = calculateYDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } break; } case StickRightUp: { if (!(axisY->getLastKnownThrottleValue() <= 0) && !(axisY->getLastKnownThrottleValue() >= 0)) { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } break; } case StickRight: { if (!(axisX->getLastKnownThrottleValue() <= 0)) { finalDistance = calculateXDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } break; } case StickRightDown: { if (!(axisY->getLastKnownThrottleValue() <= 0) && !(axisY->getLastKnownThrottleValue() <= 0)) { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } break; } case StickDown: { if (!(axisY->getLastKnownThrottleValue() <= 0)) { finalDistance = calculateYDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } break; } case StickLeftDown: { if (!(axisY->getLastKnownThrottleValue() >= 0) && !(axisY->getLastKnownThrottleValue() <= 0)) { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } break; } case StickLeft: { if (!(axisX->getLastKnownThrottleValue() >= 0)) { finalDistance = calculateXDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } break; } case StickLeftUp: { if (!(axisY->getLastKnownThrottleValue() >= 0) && !(axisY->getLastKnownThrottleValue() >= 0)) { finalDistance = calculateEightWayDiagonalDistanceFromDeadZone(axisX->getLastKnownThrottleValue(), axisY->getLastKnownThrottleValue()); } break; } default: break; } return finalDistance; } double JoyControlStick::calculateLastAccelerationDirectionalDistance() { double finalDistance = 0.0; switch (currentDirection) { case StickUp: { if (!(axisX->getLastKnownRawValue() >= 0)) finalDistance = calculateYAxisDistance(axisY->getLastKnownRawValue()); break; } case StickRightUp: { if (!(axisY->getLastKnownRawValue() <= 0) && !(axisY->getLastKnownRawValue() >= 0)) finalDistance = calculateEightWayDiagonalDistance(axisX->getLastKnownRawValue(), axisY->getLastKnownRawValue()); break; } case StickRight: { if (!(axisX->getLastKnownRawValue() <= 0)) finalDistance = calculateXAxisDistance(axisX->getLastKnownRawValue()); break; } case StickRightDown: { if (!(axisY->getLastKnownRawValue() <= 0) && !(axisY->getLastKnownRawValue() <= 0)) finalDistance = calculateEightWayDiagonalDistance(axisX->getLastKnownRawValue(), axisY->getLastKnownRawValue()); break; } case StickDown: { if (!(axisY->getLastKnownRawValue() <= 0)) finalDistance = calculateYAxisDistance(axisY->getLastKnownRawValue()); break; } case StickLeftDown: { if (!(axisY->getLastKnownRawValue() >= 0) && !(axisY->getLastKnownRawValue() <= 0)) finalDistance = calculateEightWayDiagonalDistance(axisX->getLastKnownRawValue(), axisY->getLastKnownRawValue()); break; } case StickLeft: { if (!(axisX->getLastKnownRawValue() >= 0)) finalDistance = calculateXAxisDistance(axisX->getLastKnownRawValue()); break; } case StickLeftUp: { if (!(axisY->getLastKnownRawValue() >= 0) && !(axisY->getLastKnownRawValue() >= 0)) finalDistance = calculateEightWayDiagonalDistance(axisX->getLastKnownRawValue(), axisY->getLastKnownRawValue()); break; } default: break; } return finalDistance; } /** * @brief Used to calculate the distance value that should be used for keyboard * events and distance slots * @return Distance factor that should be used for keyboard events and * distance slots */ double JoyControlStick::calculateDirectionalDistance() { double finalDistance = 0.0; switch (currentDirection) { case StickUp: { finalDistance = calculateYDistanceFromDeadZone(); break; } case StickRightUp: { finalDistance = getDistanceFromDeadZone(); break; } case StickRight: { finalDistance = calculateXDistanceFromDeadZone(); break; } case StickRightDown: { finalDistance = getDistanceFromDeadZone(); break; } case StickDown: { finalDistance = calculateYDistanceFromDeadZone(); break; } case StickLeftDown: { finalDistance = getDistanceFromDeadZone(); break; } case StickLeft: { finalDistance = calculateXDistanceFromDeadZone(); break; } case StickLeftUp: { finalDistance = getDistanceFromDeadZone(); break; } default: break; } return finalDistance; } /** * @brief Get the value for the currently active stick direction. * @return Value of the corresponding active stick direction. */ JoyControlStick::JoyStickDirections JoyControlStick::getCurrentDirection() { return currentDirection; } /** * @brief Get the value for the corresponding X axis. * @return X axis value. */ int JoyControlStick::getXCoordinate() { return axisX->getCurrentRawValue(); } /** * @brief Get the value for the corresponding Y axis. * @return Y axis value. */ int JoyControlStick::getYCoordinate() { return axisY->getCurrentRawValue(); } int JoyControlStick::getCircleXCoordinate() { int axisXValue = axisX->getCurrentRawValue(); int axisYValue = axisX->getCurrentRawValue(); if (this->circle > 0.0) axisXValue = calculateCircleXValue(axisXValue, axisYValue); return axisXValue; } int JoyControlStick::getCircleYCoordinate() { int axisXValue = axisX->getCurrentRawValue(); int axisYValue = axisY->getCurrentRawValue(); if (this->circle > 0.0) axisYValue = calculateCircleYValue(axisXValue, axisYValue); return axisYValue; } int JoyControlStick::calculateCircleXValue(int axisXValue, int axisYValue) { int value = axisXValue; if (this->circle > 0.0) { int axis1Value = axisXValue; int axis2Value = axisYValue; double angle2 = atan2(axis1Value, -axis2Value); double ang_sin = sin(angle2); double ang_cos = cos(angle2); double squareStickFull = qMin(ang_sin != 0.0 ? 1 / fabs(ang_sin) : 2, ang_cos != 0.0 ? 1 / fabs(ang_cos) : 2); double circle = this->circle; double circleStickFull = (squareStickFull - 1) * circle + 1; value = (circleStickFull > 1.0) ? floor((axisXValue / circleStickFull) + 0.5) : value; } return value; } int JoyControlStick::calculateCircleYValue(int axisXValue, int axisYValue) { int value = axisYValue; if (this->circle > 0.0) { int axis1Value = axisXValue; int axis2Value = axisYValue; double angle2 = atan2(axis1Value, -axis2Value); double ang_sin = sin(angle2); double ang_cos = cos(angle2); double squareStickFull = qMin(ang_sin != 0.0 ? 1 / fabs(ang_sin) : 2, ang_cos != 0.0 ? 1 / fabs(ang_cos) : 2); double circle = this->circle; double circleStickFull = (squareStickFull - 1) * circle + 1; value = (circleStickFull > 1.0) ? floor((axisYValue / circleStickFull) + 0.5) : value; } return value; } QList JoyControlStick::getDiagonalZoneAngles() { QList anglesList; int diagonalAngle = diagonalRange; double cardinalAngle = (360 - (diagonalAngle * 4)) / 4.0; double initialLeft = 360 - ((cardinalAngle) / 2.0); double initialRight = ((cardinalAngle) / 2.0); double upRightInitial = initialRight; double rightInitial = upRightInitial + diagonalAngle; double downRightInitial = rightInitial + cardinalAngle; double downInitial = downRightInitial + diagonalAngle; double downLeftInitial = downInitial + cardinalAngle; double leftInitial = downLeftInitial + diagonalAngle; double upLeftInitial = leftInitial + cardinalAngle; anglesList.append(initialLeft); anglesList.append(initialRight); anglesList.append(upRightInitial); anglesList.append(rightInitial); anglesList.append(downRightInitial); anglesList.append(downInitial); anglesList.append(downLeftInitial); anglesList.append(leftInitial); anglesList.append(upLeftInitial); return anglesList; } QList JoyControlStick::getFourWayCardinalZoneAngles() { QList anglesList; int zoneRange = 90; int rightInitial = 45; int downInitial = rightInitial + zoneRange; int leftInitial = downInitial + zoneRange; int upInitial = leftInitial + zoneRange; anglesList.append(rightInitial); anglesList.append(downInitial); anglesList.append(leftInitial); anglesList.append(upInitial); return anglesList; } QList JoyControlStick::getFourWayDiagonalZoneAngles() { QList anglesList; int zoneRange = 90; int upRightInitial = 0; int downRightInitial = zoneRange; int downLeftInitial = downRightInitial + zoneRange; int upLeftInitial = downLeftInitial + zoneRange; anglesList.append(upRightInitial); anglesList.append(downRightInitial); anglesList.append(downLeftInitial); anglesList.append(upLeftInitial); return anglesList; } QHash *JoyControlStick::getButtons() { return &buttons; } JoyAxis *JoyControlStick::getAxisX() { return axisX; } JoyAxis *JoyControlStick::getAxisY() { return axisY; } void JoyControlStick::replaceXAxis(JoyAxis *axis) { if (axis->getParentSet() == axisY->getParentSet()) { axisX->removeControlStick(); this->axisX = axis; this->axisX->setControlStick(this); } } void JoyControlStick::replaceYAxis(JoyAxis *axis) { if (axis->getParentSet() == axisX->getParentSet()) { axisY->removeControlStick(); this->axisY = axis; this->axisY->setControlStick(this); } } void JoyControlStick::replaceAxes(JoyAxis *axisX, JoyAxis *axisY) { if (axisX->getParentSet() == axisY->getParentSet()) { this->axisX->removeControlStick(); this->axisY->removeControlStick(); this->axisX = axisX; this->axisY = axisY; this->axisX->setControlStick(this); this->axisY->setControlStick(this); } } void JoyControlStick::setJoyMode(JoyMode mode) { currentMode = mode; emit joyModeChanged(); emit propertyUpdated(); } JoyControlStick::JoyMode JoyControlStick::getJoyMode() { return currentMode; } void JoyControlStick::releaseButtonEvents() { QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->joyEvent(false, true); } } bool JoyControlStick::isDefault() { bool value = true; value = value && (deadZone == GlobalVariables::JoyControlStick::DEFAULTDEADZONE); value = value && (maxZone == GlobalVariables::JoyControlStick::DEFAULTMAXZONE); value = value && (m_modifier_zone == GlobalVariables::JoyControlStick::DEFAULTMODIFIERZONE); value = value && (m_modifier_zone_inverted == GlobalVariables::JoyControlStick::DEFAULTMODIFIERZONEINVERTED); value = value && (diagonalRange == GlobalVariables::JoyControlStick::DEFAULTDIAGONALRANGE); value = value && (currentMode == DEFAULTMODE); value = value && qFuzzyCompare(circle, GlobalVariables::JoyControlStick::DEFAULTCIRCLE); value = value && (stickDelay == GlobalVariables::JoyControlStick::DEFAULTSTICKDELAY); QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); value = value && (button->isDefault()); } if (modifierButton != nullptr) value = value && modifierButton->isDefault(); return value; } void JoyControlStick::setButtonsMouseMode(JoyButton::JoyMouseMovementMode mode) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setMouseMode(mode); } } bool JoyControlStick::hasSameButtonsMouseMode() { bool result = true; JoyButton::JoyMouseMovementMode initialMode = JoyButton::MouseCursor; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyControlStickButton *button = iter.value(); initialMode = button->getMouseMode(); while (++iter != temphash.cend()) { button = iter.value(); JoyButton::JoyMouseMovementMode temp = button->getMouseMode(); if (temp != initialMode) { result = false; break; } } return result; } JoyButton::JoyMouseMovementMode JoyControlStick::getButtonsPresetMouseMode() { JoyButton::JoyMouseMovementMode resultMode = JoyButton::MouseCursor; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return resultMode; JoyControlStickButton *button = iter.value(); resultMode = button->getMouseMode(); while (++iter != temphash.cend()) { button = iter.value(); JoyButton::JoyMouseMovementMode temp = button->getMouseMode(); if (temp != resultMode) { resultMode = JoyButton::MouseCursor; break; } } return resultMode; } void JoyControlStick::setButtonsMouseCurve(JoyButton::JoyMouseCurve mouseCurve) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setMouseCurve(mouseCurve); } } bool JoyControlStick::hasSameButtonsMouseCurve() { bool result = true; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyControlStickButton *button = iter.value(); JoyButton::JoyMouseCurve initialCurve = button->getMouseCurve(); while (++iter != temphash.cend()) { button = iter.value(); JoyButton::JoyMouseCurve temp = button->getMouseCurve(); if (temp != initialCurve) { result = false; break; } } return result; } JoyButton::JoyMouseCurve JoyControlStick::getButtonsPresetMouseCurve() { JoyButton::JoyMouseCurve resultCurve = JoyButton::LinearCurve; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return resultCurve; JoyControlStickButton *button = iter.value(); resultCurve = button->getMouseCurve(); while (++iter != temphash.cend()) { button = iter.value(); JoyButton::JoyMouseCurve temp = button->getMouseCurve(); if (temp != resultCurve) { resultCurve = JoyButton::LinearCurve; break; } } return resultCurve; } void JoyControlStick::setButtonsSpringWidth(int value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setSpringWidth(value); } } void JoyControlStick::setButtonsSpringHeight(int value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setSpringHeight(value); } } int JoyControlStick::getButtonsPresetSpringWidth() { int presetSpringWidth = 0; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return presetSpringWidth; JoyControlStickButton *button = iter.value(); presetSpringWidth = button->getSpringWidth(); while (++iter != temphash.cend()) { button = iter.value(); int temp = button->getSpringWidth(); if (temp != presetSpringWidth) { presetSpringWidth = 0; break; } } return presetSpringWidth; } int JoyControlStick::getButtonsPresetSpringHeight() { int presetSpringHeight = 0; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return presetSpringHeight; JoyControlStickButton *button = iter.value(); presetSpringHeight = button->getSpringHeight(); while (++iter != temphash.cend()) { button = iter.value(); int temp = button->getSpringHeight(); if (temp != presetSpringHeight) { presetSpringHeight = 0; break; } } return presetSpringHeight; } void JoyControlStick::setButtonsSensitivity(double value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setSensitivity(value); } } double JoyControlStick::getButtonsPresetSensitivity() { double presetSensitivity = 1.0; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return presetSensitivity; JoyControlStickButton *button = iter.value(); presetSensitivity = button->getSensitivity(); while (++iter != temphash.cend()) { button = iter.value(); double temp = button->getSensitivity(); if (!qFuzzyCompare(temp, presetSensitivity)) { presetSensitivity = 1.0; break; } } return presetSensitivity; } QHash JoyControlStick::getApplicableButtons() { QHash temphash; if ((currentMode == StandardMode) || (currentMode == EightWayMode) || (currentMode == FourWayCardinal)) { temphash.insert(StickUp, buttons.value(StickUp)); temphash.insert(StickDown, buttons.value(StickDown)); temphash.insert(StickLeft, buttons.value(StickLeft)); temphash.insert(StickRight, buttons.value(StickRight)); } if ((currentMode == EightWayMode) || (currentMode == FourWayDiagonal)) { temphash.insert(StickLeftUp, buttons.value(StickLeftUp)); temphash.insert(StickRightUp, buttons.value(StickRightUp)); temphash.insert(StickRightDown, buttons.value(StickRightDown)); temphash.insert(StickLeftDown, buttons.value(StickLeftDown)); } return temphash; } void JoyControlStick::setStickName(QString tempName) { if ((tempName.length() <= 20) && (tempName != stickName)) { stickName = tempName; emit stickNameChanged(); // emit propertyUpdated(); } } QString JoyControlStick::getStickName() { return stickName; } void JoyControlStick::setButtonsWheelSpeedX(int value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setWheelSpeed(value, 'X'); } } void JoyControlStick::setButtonsWheelSpeedY(int value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setWheelSpeed(value, 'Y'); } } /** * @brief Get pointer to the set that a stick belongs to. * @return Pointer to the set that a stick belongs to. */ SetJoystick *JoyControlStick::getParentSet() { SetJoystick *temp = nullptr; if (axisX != nullptr) temp = axisX->getParentSet(); else if (axisY != nullptr) temp = axisY->getParentSet(); return temp; } /** * @brief Activate a stick direction button. * @param Stick direction button that will be activated. * @param [out] Pointer to the currently active button. * @param Should set changing routines be ignored. */ void JoyControlStick::performButtonPress(JoyControlStickButton *eventbutton, JoyControlStickButton *&activebutton, bool ignoresets) { activebutton = eventbutton; eventbutton->joyEvent(true, ignoresets); } /** * @brief Stick direction button to release. * @param Stick direction button that will be released. * @param Should set changing routines be ignored. */ void JoyControlStick::performButtonRelease(JoyControlStickButton *&eventbutton, bool ignoresets) { eventbutton->joyEvent(false, ignoresets); eventbutton = nullptr; } /** * @brief Determine which stick direction buttons should be active for a * standard mode stick. * @param [out] Pointer to an X axis stick direction button that should be active. * @param [out] Pointer to a Y axis stick direction button that should be active. */ void JoyControlStick::determineStandardModeEvent(JoyControlStickButton *&eventbutton1, JoyControlStickButton *&eventbutton2) { double bearing = calculateBearing(); QList anglesList = getDiagonalZoneAngles(); double initialLeft = anglesList.value(0); double initialRight = anglesList.value(1); double upRightInitial = anglesList.value(2); double rightInitial = anglesList.value(3); double downRightInitial = anglesList.value(4); double downInitial = anglesList.value(5); double downLeftInitial = anglesList.value(6); double leftInitial = anglesList.value(7); double upLeftInitial = anglesList.value(8); if ((bearing <= initialRight) || (bearing >= initialLeft)) { currentDirection = StickUp; eventbutton2 = buttons.value(StickUp); } else if ((bearing >= upRightInitial) && (bearing < rightInitial)) { currentDirection = StickRightUp; eventbutton1 = buttons.value(StickRight); eventbutton2 = buttons.value(StickUp); } else if ((bearing >= rightInitial) && (bearing < downRightInitial)) { currentDirection = StickRight; eventbutton1 = buttons.value(StickRight); } else if ((bearing >= downRightInitial) && (bearing < downInitial)) { currentDirection = StickRightDown; eventbutton1 = buttons.value(StickRight); eventbutton2 = buttons.value(StickDown); } else if ((bearing >= downInitial) && (bearing < downLeftInitial)) { currentDirection = StickDown; eventbutton2 = buttons.value(StickDown); } else if ((bearing >= downLeftInitial) && (bearing < leftInitial)) { currentDirection = StickLeftDown; eventbutton1 = buttons.value(StickLeft); eventbutton2 = buttons.value(StickDown); } else if ((bearing >= leftInitial) && (bearing < upLeftInitial)) { currentDirection = StickLeft; eventbutton1 = buttons.value(StickLeft); } else if ((bearing >= upLeftInitial) && (bearing < initialLeft)) { currentDirection = StickLeftUp; eventbutton1 = buttons.value(StickLeft); eventbutton2 = buttons.value(StickUp); } } /** * @brief Determine which stick direction button should be active for a 8 way * mode stick. * @param [out] Pointer to an X axis stick direction button that should be active. * @param [out] Pointer to a Y axis stick direction button that should be active. * @param [out] Pointer to a diagonal stick direction button that should be active. */ void JoyControlStick::determineEightWayModeEvent(JoyControlStickButton *&eventbutton1, JoyControlStickButton *&eventbutton2, JoyControlStickButton *&eventbutton3) { double bearing = calculateBearing(); QList anglesList = getDiagonalZoneAngles(); double initialLeft = anglesList.value(0); double initialRight = anglesList.value(1); double upRightInitial = anglesList.value(2); double rightInitial = anglesList.value(3); double downRightInitial = anglesList.value(4); double downInitial = anglesList.value(5); double downLeftInitial = anglesList.value(6); double leftInitial = anglesList.value(7); double upLeftInitial = anglesList.value(8); if ((bearing <= initialRight) || (bearing >= initialLeft)) { currentDirection = StickUp; eventbutton2 = buttons.value(StickUp); } else if ((bearing >= upRightInitial) && (bearing < rightInitial)) { currentDirection = StickRightUp; eventbutton3 = buttons.value(StickRightUp); } else if ((bearing >= rightInitial) && (bearing < downRightInitial)) { currentDirection = StickRight; eventbutton1 = buttons.value(StickRight); } else if ((bearing >= downRightInitial) && (bearing < downInitial)) { currentDirection = StickRightDown; eventbutton3 = buttons.value(StickRightDown); } else if ((bearing >= downInitial) && (bearing < downLeftInitial)) { currentDirection = StickDown; eventbutton2 = buttons.value(StickDown); } else if ((bearing >= downLeftInitial) && (bearing < leftInitial)) { currentDirection = StickLeftDown; eventbutton3 = buttons.value(StickLeftDown); } else if ((bearing >= leftInitial) && (bearing < upLeftInitial)) { currentDirection = StickLeft; eventbutton1 = buttons.value(StickLeft); } else if ((bearing >= upLeftInitial) && (bearing < initialLeft)) { currentDirection = StickLeftUp; eventbutton3 = buttons.value(StickLeftUp); } } /** * @brief Determine which cardinal stick direction button should be active * when using a four way cardinal stick. * @param [out] Pointer to an X axis stick direction button that should be active. * @param [out] Pointer to a Y axis stick direction button that should be active. */ void JoyControlStick::determineFourWayCardinalEvent(JoyControlStickButton *&eventbutton1, JoyControlStickButton *&eventbutton2) { double bearing = calculateBearing(); QList anglesList = getFourWayCardinalZoneAngles(); int rightInitial = anglesList.value(0); int downInitial = anglesList.value(1); int leftInitial = anglesList.value(2); int upInitial = anglesList.value(3); if ((bearing < rightInitial) || (bearing >= upInitial)) { currentDirection = StickUp; eventbutton2 = buttons.value(StickUp); } else if ((bearing >= rightInitial) && (bearing < downInitial)) { currentDirection = StickRight; eventbutton1 = buttons.value(StickRight); } else if ((bearing >= downInitial) && (bearing < leftInitial)) { currentDirection = StickDown; eventbutton2 = buttons.value(StickDown); } else if ((bearing >= leftInitial) && (bearing < upInitial)) { currentDirection = StickLeft; eventbutton1 = buttons.value(StickLeft); } } /** * @brief Determine which stick direction button should be active when using 4 way * diagonal mode. * @param [out] pointer to a diagonal stick direction button that should be active. */ void JoyControlStick::determineFourWayDiagonalEvent(JoyControlStickButton *&eventbutton3) { double bearing = calculateBearing(); QList anglesList = getFourWayDiagonalZoneAngles(); int upRightInitial = anglesList.value(0); int downRightInitial = anglesList.value(1); int downLeftInitial = anglesList.value(2); int upLeftInitial = anglesList.value(3); if ((bearing >= upRightInitial) && (bearing < downRightInitial)) { currentDirection = StickRightUp; eventbutton3 = buttons.value(StickRightUp); } else if ((bearing >= downRightInitial) && (bearing < downLeftInitial)) { currentDirection = StickRightDown; eventbutton3 = buttons.value(StickRightDown); } else if ((bearing >= downLeftInitial) && (bearing < upLeftInitial)) { currentDirection = StickLeftDown; eventbutton3 = buttons.value(StickLeftDown); } else if (bearing >= upLeftInitial) { currentDirection = StickLeftUp; eventbutton3 = buttons.value(StickLeftUp); } } /** * @brief Find the current stick direction based on a Standard mode stick. * @return Current direction the stick is positioned. */ JoyControlStick::JoyStickDirections JoyControlStick::determineStandardModeDirection() { return determineStandardModeDirection(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } JoyControlStick::JoyStickDirections JoyControlStick::determineStandardModeDirection(int axisXValue, int axisYValue) { JoyStickDirections result = StickCentered; double bearing = calculateBearing(axisXValue, axisYValue); QList anglesList = getDiagonalZoneAngles(); int initialLeft = anglesList.value(0); int initialRight = anglesList.value(1); int upRightInitial = anglesList.value(2); int rightInitial = anglesList.value(3); int downRightInitial = anglesList.value(4); int downInitial = anglesList.value(5); int downLeftInitial = anglesList.value(6); int leftInitial = anglesList.value(7); int upLeftInitial = anglesList.value(8); if ((bearing <= initialRight) || (bearing >= initialLeft)) { result = StickUp; } else if ((bearing >= upRightInitial) && (bearing < rightInitial)) { result = StickRightUp; } else if ((bearing >= rightInitial) && (bearing < downRightInitial)) { result = StickRight; } else if ((bearing >= downRightInitial) && (bearing < downInitial)) { result = StickRightDown; } else if ((bearing >= downInitial) && (bearing < downLeftInitial)) { result = StickDown; } else if ((bearing >= downLeftInitial) && (bearing < leftInitial)) { result = StickLeftDown; } else if ((bearing >= leftInitial) && (bearing < upLeftInitial)) { result = StickLeft; } else if ((bearing >= upLeftInitial) && (bearing < initialLeft)) { result = StickLeftUp; } return result; } /** * @brief Find the current stick direction based on a Eight Way mode stick. * @return Current direction the stick is positioned. */ JoyControlStick::JoyStickDirections JoyControlStick::determineEightWayModeDirection() { return determineStandardModeDirection(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } JoyControlStick::JoyStickDirections JoyControlStick::determineEightWayModeDirection(int axisXValue, int axisYValue) { return determineStandardModeDirection(axisXValue, axisYValue); } /** * @brief Find the current stick direction based on a Four Way Cardinal mode * stick. * @return Current direction the stick is positioned. */ JoyControlStick::JoyStickDirections JoyControlStick::determineFourWayCardinalDirection() { return determineFourWayCardinalDirection(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } JoyControlStick::JoyStickDirections JoyControlStick::determineFourWayCardinalDirection(int axisXValue, int axisYValue) { JoyStickDirections result = StickCentered; double bearing = calculateBearing(axisXValue, axisYValue); QList anglesList = getFourWayCardinalZoneAngles(); int rightInitial = anglesList.value(0); int downInitial = anglesList.value(1); int leftInitial = anglesList.value(2); int upInitial = anglesList.value(3); if ((bearing < rightInitial) || (bearing >= upInitial)) { result = StickUp; } else if ((bearing >= rightInitial) && (bearing < downInitial)) { result = StickRight; } else if ((bearing >= downInitial) && (bearing < leftInitial)) { result = StickDown; } else if ((bearing >= leftInitial) && (bearing < upInitial)) { result = StickLeft; } return result; } /** * @brief Find the current stick direction based on a Four Way Diagonal mode * stick. * @return Current direction the stick is positioned. */ JoyControlStick::JoyStickDirections JoyControlStick::determineFourWayDiagonalDirection() { return determineFourWayDiagonalDirection(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } JoyControlStick::JoyStickDirections JoyControlStick::determineFourWayDiagonalDirection(int axisXValue, int axisYValue) { JoyStickDirections result = StickCentered; double bearing = calculateBearing(axisXValue, axisYValue); QList anglesList = getFourWayDiagonalZoneAngles(); int upRightInitial = anglesList.value(0); int downRightInitial = anglesList.value(1); int downLeftInitial = anglesList.value(2); int upLeftInitial = anglesList.value(3); if ((bearing >= upRightInitial) && (bearing < downRightInitial)) { result = StickRightUp; } else if ((bearing >= downRightInitial) && (bearing < downLeftInitial)) { result = StickRightDown; } else if ((bearing >= downLeftInitial) && (bearing < upLeftInitial)) { result = StickLeftDown; } else if (bearing >= upLeftInitial) { result = StickLeftUp; } return result; } /** * @brief Calculate the current direction of the stick based on the values * of the X and Y axes and the current mode of the stick. * @return Current direction the stick is positioned. */ JoyControlStick::JoyStickDirections JoyControlStick::calculateStickDirection() { return calculateStickDirection(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } JoyControlStick::JoyStickDirections JoyControlStick::calculateStickDirection(int axisXValue, int axisYValue) { JoyStickDirections result = StickCentered; switch (currentMode) { case StandardMode: { result = determineStandardModeDirection(axisXValue, axisYValue); break; } case EightWayMode: { result = determineEightWayModeDirection(axisXValue, axisYValue); break; } case FourWayCardinal: { result = determineFourWayCardinalDirection(axisXValue, axisYValue); break; } case FourWayDiagonal: { result = determineFourWayDiagonalDirection(axisXValue, axisYValue); break; } } return result; } void JoyControlStick::establishPropertyUpdatedConnection() { connect(this, &JoyControlStick::propertyUpdated, getParentSet()->getInputDevice(), &InputDevice::profileEdited); } void JoyControlStick::disconnectPropertyUpdatedConnection() { disconnect(this, &JoyControlStick::propertyUpdated, getParentSet()->getInputDevice(), &InputDevice::profileEdited); } /** * @brief Check all stick buttons and see if any have slots assigned. * @return Status of whether any stick button has a slot assigned. */ bool JoyControlStick::hasSlotsAssigned() { bool hasSlots = false; QHashIterator iter(buttons); while (iter.hasNext()) { JoyButton *button = iter.next().value(); if (button != nullptr) { if (button->getAssignedSlots()->count() > 0) { hasSlots = true; iter.toBack(); } } } return hasSlots; } void JoyControlStick::setButtonsSpringRelativeStatus(bool value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setSpringRelativeStatus(value); } } bool JoyControlStick::isRelativeSpring() { bool relative = false; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return relative; JoyControlStickButton *button = iter.value(); relative = button->isRelativeSpring(); while (++iter != temphash.cend()) { button = iter.value(); bool temp = button->isRelativeSpring(); if (temp != relative) { relative = false; break; } } return relative; } /** * @brief Copy slots from all stick buttons and properties from a stick * onto another. * @param JoyControlStick object to be modified. */ void JoyControlStick::copyAssignments(JoyControlStick *destStick) { destStick->reset(); destStick->deadZone = deadZone; destStick->maxZone = maxZone; destStick->m_modifier_zone = m_modifier_zone; destStick->m_modifier_zone_inverted = m_modifier_zone_inverted; destStick->diagonalRange = diagonalRange; destStick->currentDirection = currentDirection; destStick->currentMode = currentMode; destStick->stickName = stickName; destStick->circle = circle; destStick->stickDelay = stickDelay; QHashIterator iter(destStick->buttons); while (iter.hasNext()) { JoyControlStickButton *destButton = iter.next().value(); if (destButton != nullptr) { JoyControlStickButton *sourceButton = buttons.value(destButton->getDirection()); if (sourceButton != nullptr) sourceButton->copyAssignments(destButton); } } JoyControlStickModifierButton *destModifierButton = destStick->getModifierButton(); if ((modifierButton != nullptr) && (destModifierButton != nullptr)) { modifierButton->copyAssignments(destModifierButton); } if (!destStick->isDefault()) emit propertyUpdated(); } /** * @brief Set the percentage of the outer square that should be ignored * when performing the final axis calculations. * @param Percentage represented by the range of 0.0 - 1.0. */ void JoyControlStick::setCircleAdjust(double circle) { if ((circle >= 0.0) && (circle <= 1.0)) { this->circle = circle; emit circleAdjustChange(circle); emit propertyUpdated(); } } /** * @brief Get the current percentage of the outer square that should be ignored * when performing the final axis calculations. * @return Percentage represented by the range of 0.0 - 1.0. */ double JoyControlStick::getCircleAdjust() { return circle; } /** * @brief Slot called when directionDelayTimer has timed out. The method will * call createDeskEvent. */ void JoyControlStick::stickDirectionChangeEvent() { createDeskEvent(); } void JoyControlStick::setStickDelay(int value) { if (((value >= 10) && (value <= 1000)) || (value == 0)) { this->stickDelay = value; emit stickDelayChanged(value); emit propertyUpdated(); } } int JoyControlStick::getStickDelay() { return stickDelay; } void JoyControlStick::setButtonsEasingDuration(double value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setEasingDuration(value); } } double JoyControlStick::getButtonsEasingDuration() { double result = GlobalVariables::JoyButton::DEFAULTEASINGDURATION; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyControlStickButton *button = iter.value(); result = button->getEasingDuration(); while (++iter != temphash.cend()) { button = iter.value(); double temp = button->getEasingDuration(); if (!qFuzzyCompare(temp, result)) { result = GlobalVariables::JoyButton::DEFAULTEASINGDURATION; break; } } return result; } JoyControlStickModifierButton *JoyControlStick::getModifierButton() { return modifierButton; } void JoyControlStick::queueJoyEvent(bool ignoresets) { Q_UNUSED(ignoresets) pendingStickEvent = true; } bool JoyControlStick::hasPendingEvent() { return pendingStickEvent; } void JoyControlStick::activatePendingEvent() { if (pendingStickEvent) { bool ignoresets = false; joyEvent(ignoresets); pendingStickEvent = false; } } void JoyControlStick::clearPendingEvent() { pendingStickEvent = false; } void JoyControlStick::setButtonsExtraAccelerationStatus(bool enabled) { QHashIterator iter(getApplicableButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button != nullptr) button->setExtraAccelerationStatus(enabled); } } bool JoyControlStick::getButtonsExtraAccelerationStatus() { bool result = false; QHashIterator iter(getApplicableButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button != nullptr) { bool temp = button->isExtraAccelerationEnabled(); if (!temp) { result = false; iter.toBack(); } else { result = temp; } } } return result; } void JoyControlStick::setButtonsExtraAccelerationMultiplier(double value) { QHashIterator iter(getApplicableButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button != nullptr) button->setExtraAccelerationMultiplier(value); } } double JoyControlStick::getButtonsExtraAccelerationMultiplier() { double result = GlobalVariables::JoyButton::DEFAULTEXTRACCELVALUE; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyControlStickButton *button = iter.value(); if (button != nullptr) result = button->getExtraAccelerationMultiplier(); while (++iter != temphash.cend()) { button = iter.value(); if (button != nullptr) { double temp = button->getExtraAccelerationMultiplier(); if (!qFuzzyCompare(temp, result)) { result = GlobalVariables::JoyButton::DEFAULTEXTRACCELVALUE; break; } } } return result; } void JoyControlStick::setButtonsStartAccelerationMultiplier(double value) { QHashIterator iter(getApplicableButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button != nullptr) button->setStartAccelMultiplier(value); } } double JoyControlStick::getButtonsStartAccelerationMultiplier() { double result = GlobalVariables::JoyButton::DEFAULTSTARTACCELMULTIPLIER; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyControlStickButton *button = iter.value(); if (button != nullptr) result = button->getStartAccelMultiplier(); while (++iter != temphash.cend()) { button = iter.value(); if (button != nullptr) { double temp = button->getStartAccelMultiplier(); if (!qFuzzyCompare(temp, result)) { result = GlobalVariables::JoyButton::DEFAULTSTARTACCELMULTIPLIER; break; } } } return result; } void JoyControlStick::setButtonsMinAccelerationThreshold(double value) { QHashIterator iter(getApplicableButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button != nullptr) button->setMinAccelThreshold(value); } } double JoyControlStick::getButtonsMinAccelerationThreshold() { double result = GlobalVariables::JoyButton::DEFAULTMINACCELTHRESHOLD; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyControlStickButton *button = iter.value(); if (button != nullptr) result = button->getMinAccelThreshold(); while (++iter != temphash.cend()) { button = iter.value(); if (button != nullptr) { double temp = button->getMinAccelThreshold(); if (!qFuzzyCompare(temp, result)) { result = GlobalVariables::JoyButton::DEFAULTMINACCELTHRESHOLD; break; } } } return result; } void JoyControlStick::setButtonsMaxAccelerationThreshold(double value) { QHashIterator iter(getApplicableButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button != nullptr) button->setMaxAccelThreshold(value); } } double JoyControlStick::getButtonsMaxAccelerationThreshold() { double result = GlobalVariables::JoyButton::DEFAULTMAXACCELTHRESHOLD; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyControlStickButton *button = iter.value(); if (button != nullptr) result = button->getMaxAccelThreshold(); while (++iter != temphash.cend()) { button = iter.value(); if (button != nullptr) { double temp = button->getMaxAccelThreshold(); if (!qFuzzyCompare(temp, result)) { result = GlobalVariables::JoyButton::DEFAULTMAXACCELTHRESHOLD; break; } } } return result; } void JoyControlStick::setButtonsAccelerationExtraDuration(double value) { QHashIterator iter(getApplicableButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button != nullptr) button->setAccelExtraDuration(value); } } double JoyControlStick::getButtonsAccelerationEasingDuration() { double result = GlobalVariables::JoyButton::DEFAULTACCELEASINGDURATION; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyControlStickButton *button = iter.value(); if (button != nullptr) result = button->getAccelExtraDuration(); while (++iter != temphash.cend()) { button = iter.value(); if (button != nullptr) { double temp = button->getAccelExtraDuration(); if (!qFuzzyCompare(temp, result)) { result = GlobalVariables::JoyButton::DEFAULTACCELEASINGDURATION; break; } } } return result; } void JoyControlStick::setButtonsSpringDeadCircleMultiplier(int value) { QHashIterator iter(getApplicableButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button != nullptr) { button->setSpringDeadCircleMultiplier(value); } } } int JoyControlStick::getButtonsSpringDeadCircleMultiplier() { int result = GlobalVariables::JoyButton::DEFAULTSPRINGRELEASERADIUS; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyControlStickButton *button = iter.value(); if (button != nullptr) result = button->getSpringDeadCircleMultiplier(); while (++iter != temphash.cend()) { button = iter.value(); if (button != nullptr) { int temp = button->getSpringDeadCircleMultiplier(); if (temp != result) { result = GlobalVariables::JoyButton::DEFAULTSPRINGRELEASERADIUS; break; } } } return result; } double JoyControlStick::calculateAccelerationDistance(JoyControlStickButton *button) { double finalDistance = 0.0; switch (currentDirection) { case StickUp: { if (axisY->getCurrentRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getCurrentRawValue()); } break; } case StickRightUp: { switch (button->getJoyNumber()) { case 1: if (axisY->getCurrentRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getCurrentRawValue()); } break; case 2: if ((axisX->getCurrentRawValue() <= 0) || (axisY->getCurrentRawValue() >= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistance(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } break; case 3: if (axisX->getCurrentRawValue() < 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getCurrentRawValue()); } break; } break; } case StickRight: { if (axisX->getCurrentRawValue() < 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getCurrentRawValue()); } break; } case StickRightDown: { switch (button->getJoyNumber()) { case 3: if (axisX->getCurrentRawValue() < 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getCurrentRawValue()); } break; case 4: if ((axisX->getCurrentRawValue() <= 0) || (axisY->getCurrentRawValue() <= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistance(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } break; case 5: if (axisY->getCurrentRawValue() < 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getCurrentRawValue()); } break; } break; } case StickDown: { if (axisY->getCurrentRawValue() <= 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getCurrentRawValue()); } break; } case StickLeftDown: { switch (button->getJoyNumber()) { case 5: if (axisY->getCurrentRawValue() < 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getCurrentRawValue()); } break; case 6: if ((axisX->getCurrentRawValue() >= 0) || (axisY->getCurrentRawValue() <= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistance(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } break; case 7: if (axisX->getCurrentRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getCurrentRawValue()); } break; } break; } case StickLeft: { if (axisX->getCurrentRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getCurrentRawValue()); } break; } case StickLeftUp: { switch (button->getJoyNumber()) { case 1: if (axisY->getCurrentRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getCurrentRawValue()); } break; case 7: if (axisX->getCurrentRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getCurrentRawValue()); } break; case 8: if ((axisX->getCurrentRawValue() >= 0) || (axisY->getCurrentRawValue() >= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistance(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } break; } break; } default: break; } return finalDistance; } // TODO: Maybe change method name. double JoyControlStick::calculateLastAccelerationButtonDistance(JoyControlStickButton *button) { double finalDistance = 0.0; switch (currentDirection) { case StickUp: { if (axisY->getLastKnownRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getLastKnownRawValue()); } break; } case StickRightUp: { switch (button->getJoyNumber()) { case StickRight: { if (axisX->getLastKnownRawValue() <= 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getLastKnownRawValue()); } break; } case StickUp: { if (axisY->getLastKnownRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getLastKnownRawValue()); } break; } case StickRightUp: { if ((axisX->getLastKnownRawValue() <= 0) || (axisY->getLastKnownRawValue() >= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistance(axisX->getLastKnownRawValue(), axisY->getLastKnownRawValue()); } break; } } break; } case StickRight: { if (axisX->getLastKnownRawValue() <= 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getLastKnownRawValue()); } break; } case StickRightDown: { switch (button->getJoyNumber()) { case StickRight: { if (axisX->getLastKnownRawValue() <= 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getLastKnownRawValue()); } break; } case StickDown: { if (axisY->getLastKnownRawValue() <= 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getLastKnownRawValue()); } break; } case StickRightDown: { if ((axisX->getLastKnownRawValue() <= 0) || (axisY->getLastKnownRawValue() <= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistance(axisX->getLastKnownRawValue(), axisY->getLastKnownRawValue()); } break; } } break; } case StickDown: { if (axisY->getLastKnownRawValue() <= 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getLastKnownRawValue()); } break; } case StickLeftDown: { switch (button->getJoyNumber()) { case 7: { if (axisX->getLastKnownRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getLastKnownRawValue()); } break; } case 5: { if (axisY->getLastKnownRawValue() <= 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getLastKnownRawValue()); } break; } case 6: { if ((axisX->getLastKnownRawValue() >= 0) || (axisY->getLastKnownRawValue() <= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistance(axisX->getLastKnownRawValue(), axisY->getLastKnownRawValue()); } break; } } break; } case StickLeft: { if (axisX->getLastKnownRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getLastKnownRawValue()); } break; } case StickLeftUp: { switch (button->getJoyNumber()) { case 7: { if (axisX->getLastKnownRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateXAxisDistance(axisX->getLastKnownRawValue()); } break; } case 1: { if (axisY->getLastKnownRawValue() >= 0) { finalDistance = 0.0; } else { finalDistance = calculateYAxisDistance(axisY->getLastKnownRawValue()); } break; } case 8: { if ((axisX->getLastKnownRawValue() >= 0) || (axisY->getLastKnownRawValue() >= 0)) { finalDistance = 0.0; } else { finalDistance = calculateEightWayDiagonalDistance(axisX->getLastKnownRawValue(), axisY->getLastKnownRawValue()); } break; } } break; } default: break; } return finalDistance; } double JoyControlStick::calculateXAxisDistance(int axisXValue) { int axis1Value = axisXValue; double distance = axis1Value / static_cast(maxZone); if (distance < -1.0) distance = -1.0; else if (distance > 1.0) distance = 1.0; qDebug() << "DISTANCE: " << distance; return distance; } double JoyControlStick::calculateYAxisDistance(int axisYValue) { int axis2Value = axisYValue; double distance = axis2Value / static_cast(maxZone); if (distance < -1.0) distance = -1.0; else if (distance > 1.0) distance = 1.0; return distance; } double JoyControlStick::calculateEightWayDiagonalDistanceFromDeadZone() { return calculateEightWayDiagonalDistanceFromDeadZone(axisX->getCurrentRawValue(), axisY->getCurrentRawValue()); } double JoyControlStick::calculateEightWayDiagonalDistanceFromDeadZone(int axisXValue, int axisYValue) { double distance = 0.0; double radius = getDistanceFromDeadZone(axisXValue, axisYValue); double bearing = calculateBearing(axisXValue, axisYValue); int relativeBearing = static_cast(bearing) % 90; int diagonalAngle = relativeBearing; if (relativeBearing > 45) diagonalAngle = 90 - relativeBearing; distance = radius * (diagonalAngle / 45.0); return distance; } double JoyControlStick::calculateEightWayDiagonalDistance(int axisXValue, int axisYValue) { double distance = 0.0; double radius = getRadialDistance(axisXValue, axisYValue); double bearing = calculateBearing(axisXValue, axisYValue); int relativeBearing = static_cast(bearing) % 90; int diagonalAngle = relativeBearing; if (relativeBearing > 45) diagonalAngle = 90 - relativeBearing; distance = radius * (diagonalAngle / 45.0); return distance; } double JoyControlStick::calculateXDiagonalDeadZone(int axisXValue, int axisYValue) { double diagonalDeadZone = 0.0; JoyStickDirections direction = calculateStickDirection(axisXValue, axisYValue); if (diagonalRange < 90) { if ((direction == StickRightUp) || (direction == StickRight)) { QList tempangles = getDiagonalZoneAngles(); double maxangle = tempangles.at(3); double mindeadX = fabs(deadZone * cos(maxangle * GlobalVariables::JoyControlStick::PI / 180.0)); diagonalDeadZone = mindeadX; } else if ((direction == StickRightDown) || (direction == StickDown)) { QList tempangles = getDiagonalZoneAngles(); double maxangle = tempangles.at(5); double mindeadX = fabs(deadZone * cos((maxangle - 90.0) * GlobalVariables::JoyControlStick::PI / 180.0)); diagonalDeadZone = mindeadX; } else if ((direction == StickLeftDown) || (direction == StickLeft)) { QList tempangles = getDiagonalZoneAngles(); double maxangle = tempangles.at(7); double mindeadX = fabs(deadZone * cos((maxangle - 180.0) * GlobalVariables::JoyControlStick::PI / 180.0)); diagonalDeadZone = mindeadX; } else if ((direction == StickLeftUp) || (direction == StickUp)) { QList tempangles = getDiagonalZoneAngles(); double maxangle = tempangles.at(1); double mindeadX = fabs(deadZone * cos((maxangle - 270.0) * GlobalVariables::JoyControlStick::PI / 180.0)); diagonalDeadZone = mindeadX; } else { diagonalDeadZone = 0.0; } } else { diagonalDeadZone = 0.0; } return diagonalDeadZone; } double JoyControlStick::calculateYDiagonalDeadZone(int axisXValue, int axisYValue) { double diagonalDeadZone = 0.0; JoyStickDirections direction = calculateStickDirection(axisXValue, axisYValue); if (diagonalRange < 90) { if ((direction == StickRightUp) || (direction == StickUp)) { QList tempangles = getDiagonalZoneAngles(); double minangle = tempangles.at(1); double mindeadY = fabs(deadZone * sin(minangle * GlobalVariables::JoyControlStick::PI / 180.0)); diagonalDeadZone = mindeadY; } else if ((direction == StickRightDown) || (direction == StickRight)) { QList tempfuck = getDiagonalZoneAngles(); double minangle = tempfuck.at(4); double mindeadY = fabs(deadZone * sin((minangle - 90.0) * GlobalVariables::JoyControlStick::PI / 180.0)); diagonalDeadZone = mindeadY; } else if ((direction == StickLeftDown) || (direction == StickDown)) { QList tempangles = getDiagonalZoneAngles(); double minangle = tempangles.at(6); double mindeadY = fabs(deadZone * sin((minangle - 180.0) * GlobalVariables::JoyControlStick::PI / 180.0)); diagonalDeadZone = mindeadY; } else if ((direction == StickLeftUp) || (direction == StickLeft)) { QList tempangles = getDiagonalZoneAngles(); double minangle = tempangles.at(8); double mindeadY = fabs(deadZone * sin((minangle - 270.0) * GlobalVariables::JoyControlStick::PI / 180.0)); diagonalDeadZone = mindeadY; } else { diagonalDeadZone = 0.0; } } else { diagonalDeadZone = 0.0; } return diagonalDeadZone; } double JoyControlStick::getSpringDeadCircleX() { double result = 0.0; double angle2 = 0.0; int axis1Value = 0; int axis2Value = 0; if ((axisX->getCurrentRawValue() == 0) && (axisY->getCurrentRawValue() == 0)) { // Stick moved back to absolute center. Use previously available values // to find stick angle. angle2 = atan2(axisX->getLastKnownRawValue(), -axisY->getLastKnownRawValue()); axis1Value = axisX->getLastKnownRawValue(); axis2Value = axisY->getLastKnownRawValue(); } else { // Use current axis values to find stick angle. angle2 = atan2(axisX->getCurrentRawValue(), -axisY->getCurrentRawValue()); axis1Value = axisX->getCurrentRawValue(); axis2Value = axisY->getCurrentRawValue(); } double ang_sin = sin(angle2); double ang_cos = cos(angle2); int deadX = abs(floor(deadZone * ang_sin + 0.5)); double diagonalDeadX = calculateXDiagonalDeadZone(axis1Value, axis2Value); double squareStickFullPhi = qMin(ang_sin != 0.0 ? 1 / fabs(ang_sin) : 2, ang_cos != 0.0 ? 1 / fabs(ang_cos) : 2); double circle = this->circle; double circleStickFull = (squareStickFullPhi - 1) * circle + 1; double adjustedDeadXZone = circleStickFull > 1.0 ? (deadX / circleStickFull) : deadX; double finalDeadZoneX = adjustedDeadXZone - diagonalDeadX; double maxRange = static_cast(deadZone) - diagonalDeadX; if (maxRange != 0.0) result = finalDeadZoneX / maxRange; return result; } double JoyControlStick::getSpringDeadCircleY() { double result = 0.0; double angle2 = 0.0; int axis1Value = 0; int axis2Value = 0; if ((axisX->getCurrentRawValue() == 0) && (axisY->getCurrentRawValue() == 0)) { // Stick moved back to absolute center. Use previously available values // to find stick angle. angle2 = atan2(axisX->getLastKnownRawValue(), -axisY->getLastKnownRawValue()); axis1Value = axisX->getLastKnownRawValue(); axis2Value = axisY->getLastKnownRawValue(); } else { // Use current axis values to find stick angle. angle2 = atan2(axisX->getCurrentRawValue(), -axisY->getCurrentRawValue()); axis1Value = axisX->getCurrentRawValue(); axis2Value = axisY->getCurrentRawValue(); } double ang_sin = sin(angle2); double ang_cos = cos(angle2); int deadY = abs(floor(deadZone * ang_cos + 0.5)); double diagonalDeadY = calculateYDiagonalDeadZone(axis1Value, axis2Value); double squareStickFullPhi = qMin(ang_sin != 0.0 ? 1 / fabs(ang_sin) : 2, ang_cos != 0.0 ? 1 / fabs(ang_cos) : 2); double circle = this->circle; double circleStickFull = (squareStickFullPhi - 1) * circle + 1; double adjustedDeadYZone = (circleStickFull > 1.0) ? (deadY / circleStickFull) : deadY; double finalDeadZoneY = adjustedDeadYZone - diagonalDeadY; double maxRange = static_cast(deadZone) - diagonalDeadY; if (maxRange != 0.0) result = finalDeadZoneY / maxRange; return result; } void JoyControlStick::setButtonsExtraAccelCurve(JoyButton::JoyExtraAccelerationCurve curve) { QHashIterator iter(getApplicableButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button != nullptr) { button->setExtraAccelerationCurve(curve); } } } JoyButton::JoyExtraAccelerationCurve JoyControlStick::getButtonsExtraAccelerationCurve() { JoyButton::JoyExtraAccelerationCurve result = JoyButton::LinearAccelCurve; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyControlStickButton *button = iter.value(); if (button != nullptr) result = button->getExtraAccelerationCurve(); while (++iter != temphash.cend()) { button = iter.value(); if (button != nullptr) { JoyButton::JoyExtraAccelerationCurve temp = button->getExtraAccelerationCurve(); if (temp != result) { result = JoyButton::LinearAccelCurve; break; } } } return result; } void JoyControlStick::setDirButtonsUpdateInitAccel(JoyControlStick::JoyStickDirections direction, bool state) { QHash apphash = getButtonsForDirection(direction); // QVERIFY(apphash.isEmpty() == false); QHashIterator iter(apphash); // QVERIFY(iter.hasNext() == true); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setUpdateInitAccel(state); } } QHash JoyControlStick::getButtonsForDirection(JoyControlStick::JoyStickDirections direction) { QHash temphash; switch (currentMode) { case StandardMode: { if (direction & JoyControlStick::StickUp) { JoyControlStickButton *button = this->buttons.value(JoyControlStick::StickUp); temphash.insert(JoyControlStick::StickUp, button); } if (direction & JoyControlStick::StickRight) { JoyControlStickButton *button = this->buttons.value(JoyControlStick::StickRight); temphash.insert(JoyControlStick::StickRight, button); } if (direction & JoyControlStick::StickDown) { JoyControlStickButton *button = this->buttons.value(JoyControlStick::StickDown); temphash.insert(JoyControlStick::StickDown, button); } if (direction & JoyControlStick::StickLeft) { JoyControlStickButton *button = this->buttons.value(JoyControlStick::StickLeft); temphash.insert(JoyControlStick::StickLeft, button); } break; } case EightWayMode: { if ((direction == JoyControlStick::StickUp) || (direction == JoyControlStick::StickDown) || (direction == JoyControlStick::StickLeft) || (direction == JoyControlStick::StickRight) || (direction == JoyControlStick::StickRightUp) || (direction == JoyControlStick::StickRightDown) || (direction == JoyControlStick::StickLeftDown) || (direction == JoyControlStick::StickLeftUp)) { temphash.insert(direction, buttons.value(direction)); } break; } case FourWayCardinal: { if ((direction == JoyControlStick::StickUp) || (direction == JoyControlStick::StickDown) || (direction == JoyControlStick::StickLeft) || (direction == JoyControlStick::StickRight)) { temphash.insert(direction, buttons.value(direction)); } break; } case FourWayDiagonal: { if ((direction == JoyControlStick::StickRightUp) || (direction == JoyControlStick::StickRightDown) || (direction == JoyControlStick::StickLeftDown) || (direction == JoyControlStick::StickLeftUp)) { temphash.insert(direction, buttons.value(direction)); } break; } } return temphash; } AntiMicroX-antimicrox-b300273/src/joycontrolstick.h000066400000000000000000000336671471077622000223710ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYCONTROLSTICK_H #define JOYCONTROLSTICK_H #include "joybuttontypes/joybutton.h" #include "joycontrolstickdirectionstype.h" #include class JoyAxis; class JoyControlStickButton; class JoyControlStickModifierButton; class QXmlStreamReader; class QXmlStreamWriter; /** * @brief Represents stick of a joystick * */ class JoyControlStick : public QObject, public JoyStickDirectionsType { Q_OBJECT public: explicit JoyControlStick(JoyAxis *axisX, JoyAxis *axisY, int index, int originset, QObject *parent); ~JoyControlStick(); enum JoyMode { StandardMode = 0, EightWayMode, FourWayCardinal, FourWayDiagonal }; void joyEvent(bool ignoresets = false); // JoyControlStickEvent class void setIndex(int index); void replaceXAxis(JoyAxis *axis); // JoyControlStickAxes class void replaceYAxis(JoyAxis *axis); // JoyControlStickAxes class void replaceAxes(JoyAxis *axisX, JoyAxis *axisY); // JoyControlStickAxes class void releaseButtonEvents(); // JoyControlStickEvent class void copyAssignments(JoyControlStick *destStick); void queueJoyEvent(bool ignoresets); // JoyControlStickEvent class void activatePendingEvent(); // JoyControlStickEvent class void clearPendingEvent(); // JoyControlStickEvent class bool inDeadZone(); bool hasSlotsAssigned(); bool isRelativeSpring(); bool hasPendingEvent(); // JoyControlStickEvent class bool isCalibrated() const; void resetCalibration(); void getCalibration(double *offsetX, double *gainX, double *offsetY, double *gainY) const; void setCalibration(double offsetX, double gainX, double offsetY, double gainY); int getDeadZone(); int getDiagonalRange(); int getIndex(); int getRealJoyIndex(); int getMaxZone(); int getModifierZone() const; bool getModifierZoneInverted() const; int getCurrentlyAssignedSet(); int getXCoordinate(); int getYCoordinate(); int getCircleXCoordinate(); int getCircleYCoordinate(); int getStickDelay(); double getDistanceFromDeadZone(); // JoyControlStickAxes class double getDistanceFromDeadZone(int axisXValue, int axisYValue); // JoyControlStickAxes class double getAbsoluteRawDistance(); // JoyControlStickAxes class double getAbsoluteRawDistance(int axisXValue, int axisYValue); // JoyControlStickAxes class double getNormalizedAbsoluteDistance(); // JoyControlStickAxes class double calculateBearing(); // JoyControlStickAxes class double calculateBearing(int axisXValue, int axisYValue); // JoyControlStickAxes class double calculateMouseDirectionalDistance(JoyControlStickButton *button); // JoyControlStickAxes class double calculateDirectionalDistance(); // JoyControlStickAxes class double calculateLastDirectionalDistance(); // JoyControlStickAxes class double calculateLastMouseDirectionalDistance(JoyControlStickButton *button); // JoyControlStickAxes class double calculateLastAccelerationButtonDistance(JoyControlStickButton *button); // JoyControlStickAxes class double calculateAccelerationDistance(JoyControlStickButton *button); // JoyControlStickAxis class double calculateXAxisDistance(int axisXValue); // JoyControlStickAxis class double calculateYAxisDistance(int axisYValue); // JoyControlStickAxis class double calculateLastAccelerationDirectionalDistance(); // JoyControlStickAxis class double getRadialDistance(int axisXValue, int axisYValue); // JoyControlStickAxis class double getCircleAdjust(); // JoyControlStickAxis class double getButtonsEasingDuration(); double getSpringDeadCircleX(); // JoyControlStickAxis class double getSpringDeadCircleY(); // JoyControlStickAxis class QString getStickName(); virtual QString getName(bool forceFullFormat = false, bool displayNames = false); virtual QString getPartialName(bool forceFullFormat = false, bool displayNames = false); JoyStickDirections getCurrentDirection(); // JoyControlStickAxes class QList getDiagonalZoneAngles(); // JoyControlStickAxes class QList getFourWayCardinalZoneAngles(); // JoyControlStickAxes class QList getFourWayDiagonalZoneAngles(); // JoyControlStickAxes class QHash *getButtons(); JoyControlStickButton *getDirectionButton(JoyStickDirections direction); // JoyControlStickAxes class JoyControlStickModifierButton *getModifierButton(); SetJoystick *getParentSet(); JoyAxis *getAxisX(); // JoyControlStickAxes class JoyAxis *getAxisY(); // JoyControlStickAxes class void setJoyMode(JoyMode mode); JoyMode getJoyMode(); void setButtonsMouseMode(JoyButton::JoyMouseMovementMode mode); bool hasSameButtonsMouseMode(); JoyButton::JoyMouseMovementMode getButtonsPresetMouseMode(); void setButtonsMouseCurve(JoyButton::JoyMouseCurve mouseCurve); bool hasSameButtonsMouseCurve(); JoyButton::JoyMouseCurve getButtonsPresetMouseCurve(); void setButtonsSpringWidth(int value); int getButtonsPresetSpringWidth(); void setButtonsSpringHeight(int value); int getButtonsPresetSpringHeight(); void setButtonsSensitivity(double value); double getButtonsPresetSensitivity(); void setButtonsWheelSpeedX(int value); void setButtonsWheelSpeedY(int value); void setButtonsExtraAccelerationStatus(bool enabled); bool getButtonsExtraAccelerationStatus(); void setButtonsExtraAccelerationMultiplier(double value); double getButtonsExtraAccelerationMultiplier(); void setButtonsStartAccelerationMultiplier(double value); double getButtonsStartAccelerationMultiplier(); void setButtonsMinAccelerationThreshold(double value); double getButtonsMinAccelerationThreshold(); void setButtonsMaxAccelerationThreshold(double value); double getButtonsMaxAccelerationThreshold(); void setButtonsAccelerationExtraDuration(double value); double getButtonsAccelerationEasingDuration(); void setButtonsSpringDeadCircleMultiplier(int value); int getButtonsSpringDeadCircleMultiplier(); void setButtonsExtraAccelCurve(JoyButton::JoyExtraAccelerationCurve curve); JoyButton::JoyExtraAccelerationCurve getButtonsExtraAccelerationCurve(); QHash getButtonsForDirection(JoyControlStick::JoyStickDirections direction); // JoyControlStickAxes class void setDirButtonsUpdateInitAccel(JoyControlStick::JoyStickDirections direction, bool state); // JoyControlStickAxes class double calculateXDiagonalDeadZone(int axisXValue, int axisYValue); // JoyControlStickAxes class double calculateYDiagonalDeadZone(int axisXValue, int axisYValue); // JoyControlStickAxes class virtual bool isDefault(); virtual void setDefaultStickName(QString tempname); virtual QString getDefaultStickName(); virtual void readConfig(QXmlStreamReader *xml); // JoyControlStickXml class virtual void writeConfig(QXmlStreamWriter *xml); // JoyControlStickXml class static const JoyMode DEFAULTMODE; protected: virtual void populateButtons(); void createDeskEvent(bool ignoresets = false); // JoyControlStickEvent class void determineStandardModeEvent(JoyControlStickButton *&eventbutton1, JoyControlStickButton *&eventbutton2); // JoyControlStickEvent class void determineEightWayModeEvent(JoyControlStickButton *&eventbutton1, JoyControlStickButton *&eventbutton2, JoyControlStickButton *&eventbutton3); // JoyControlStickEvent class void determineFourWayCardinalEvent(JoyControlStickButton *&eventbutton1, JoyControlStickButton *&eventbutton2); // JoyControlStickEvent class void determineFourWayDiagonalEvent(JoyControlStickButton *&eventbutton3); // JoyControlStickEvent class JoyControlStick::JoyStickDirections determineStandardModeDirection(); // JoyControlStickAxes class JoyControlStick::JoyStickDirections determineStandardModeDirection(int axisXValue, int axisYValue); // JoyControlStickAxes class JoyControlStick::JoyStickDirections determineEightWayModeDirection(); // JoyControlStickAxes class JoyControlStick::JoyStickDirections determineEightWayModeDirection(int axisXValue, int axisYValue); // JoyControlStickAxes class JoyControlStick::JoyStickDirections determineFourWayCardinalDirection(); // JoyControlStickAxes class JoyControlStick::JoyStickDirections determineFourWayCardinalDirection(int axisXValue, int axisYValue); // JoyControlStickAxes class JoyControlStick::JoyStickDirections determineFourWayDiagonalDirection(); // JoyControlStickAxes class JoyControlStick::JoyStickDirections determineFourWayDiagonalDirection(int axisXValue, int axisYValue); // JoyControlStickAxes class JoyControlStick::JoyStickDirections calculateStickDirection(); // JoyControlStickAxes class JoyControlStick::JoyStickDirections calculateStickDirection(int axisXValue, int axisYValue); // JoyControlStickAxes class void performButtonPress(JoyControlStickButton *eventbutton, JoyControlStickButton *&activebutton, bool ignoresets); void performButtonRelease(JoyControlStickButton *&eventbutton, bool ignoresets); void resetButtons(); double calculateXDistanceFromDeadZone(bool interpolate = false); // JoyControlStickAxes class double calculateXDistanceFromDeadZone(int axisXValue, int axisYValue, bool interpolate = false); // JoyControlStickAxes class double calculateYDistanceFromDeadZone(bool interpolate = false); // JoyControlStickAxes class double calculateYDistanceFromDeadZone(int axisXValue, int axisYValue, bool interpolate = false); // JoyControlStickAxes class int calculateCircleXValue(int axisXValue, int axisYValue); // JoyControlStickAxes class int calculateCircleYValue(int axisXValue, int axisYValue); // JoyControlStickAxes class double calculateEightWayDiagonalDistanceFromDeadZone(); // JoyControlStickAxes class double calculateEightWayDiagonalDistanceFromDeadZone(int axisXValue, int axisYValue); // JoyControlStickAxes class double calculateEightWayDiagonalDistance(int axisXValue, int axisYValue); // JoyControlStickAxes class QHash getApplicableButtons(); void clearPendingAxisEvents(); // JoyControlStickEvent class signals: void moved(int xaxis, int yaxis); void active(int xaxis, int yaxis); void released(int axis, int yaxis); void deadZoneChanged(int value); void diagonalRangeChanged(int value); void maxZoneChanged(int value); void modifierZoneChanged(int value); void circleAdjustChange(double circle); void stickDelayChanged(int value); void stickNameChanged(); void joyModeChanged(); void propertyUpdated(); public slots: void reset(); void setDeadZone(int value); void setMaxZone(int value); void setModifierZone(int value); void setModifierZoneInverted(bool value); void setDiagonalRange(int value); void setStickName(QString tempName); void setButtonsSpringRelativeStatus(bool value); void setCircleAdjust(double circle); // JoyControlStickAxes class void setStickDelay(int value); void setButtonsEasingDuration(double value); void establishPropertyUpdatedConnection(); void disconnectPropertyUpdatedConnection(); private slots: void stickDirectionChangeEvent(); // JoyControlStickEvent class private: int originset; int deadZone; int m_modifier_zone; bool m_modifier_zone_inverted; int diagonalRange; int maxZone; int index; int stickDelay; // unsigned int double circle; bool isActive; bool safezone; bool pendingStickEvent; QPointer axisX; QPointer axisY; JoyControlStickButton *activeButton1; JoyControlStickButton *activeButton2; JoyControlStickButton *activeButton3; JoyStickDirections currentDirection; JoyMode currentMode; QString stickName; QString defaultStickName; QTimer directionDelayTimer; QHash buttons; JoyControlStickModifierButton *modifierButton; void populateStickBtns(); }; #endif // JOYCONTROLSTICK_H AntiMicroX-antimicrox-b300273/src/joycontrolstickbuttonpushbutton.cpp000066400000000000000000000111701471077622000262750ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joycontrolstickbuttonpushbutton.h" #include "joybuttoncontextmenu.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joybuttontypes/joycontrolstickmodifierbutton.h" #include "joycontrolstick.h" #include "logger.h" #include #include JoyControlStickButtonPushButton::JoyControlStickButtonPushButton(JoyControlStickButton *button, bool displayNames, QWidget *parent) : FlashButtonWidget(displayNames, parent) { this->button = button; refreshLabel(); enableFlashes(); tryFlash(); this->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &JoyControlStickButtonPushButton::customContextMenuRequested, this, &JoyControlStickButtonPushButton::showContextMenu); connect(button, &JoyControlStickButton::propertyUpdated, this, &JoyControlStickButtonPushButton::refreshLabel); connect(button, &JoyControlStickButton::activeZoneChanged, this, &JoyControlStickButtonPushButton::refreshLabel); connect(button->getStick()->getModifierButton(), &JoyControlStickModifierButton::activeZoneChanged, this, &JoyControlStickButtonPushButton::refreshLabel); } JoyControlStickButton *JoyControlStickButtonPushButton::getButton() { return button; } void JoyControlStickButtonPushButton::setButton(JoyControlStickButton *button) { disableFlashes(); if (this->button != nullptr) { disconnect(button, &JoyControlStickButton::propertyUpdated, this, &JoyControlStickButtonPushButton::refreshLabel); disconnect(this->button, &JoyControlStickButton::activeZoneChanged, this, &JoyControlStickButtonPushButton::refreshLabel); } this->button = button; refreshLabel(); enableFlashes(); connect(button, &JoyControlStickButton::propertyUpdated, this, &JoyControlStickButtonPushButton::refreshLabel); connect(button, &JoyControlStickButton::activeZoneChanged, this, &JoyControlStickButtonPushButton::refreshLabel, Qt::QueuedConnection); } void JoyControlStickButtonPushButton::disableFlashes() { if (button != nullptr) { disconnect(button, &JoyControlStickButton::clicked, this, &JoyControlStickButtonPushButton::flash); disconnect(button, &JoyControlStickButton::released, this, &JoyControlStickButtonPushButton::unflash); } this->unflash(); } void JoyControlStickButtonPushButton::enableFlashes() { if (button != nullptr) { connect(button, &JoyControlStickButton::clicked, this, &JoyControlStickButtonPushButton::flash, Qt::QueuedConnection); connect(button, &JoyControlStickButton::released, this, &JoyControlStickButtonPushButton::unflash, Qt::QueuedConnection); } } /** * @brief Generate the string that will be displayed on the button * @return Display string */ QString JoyControlStickButtonPushButton::generateLabel() { QString temp = QString(); if (button != nullptr) { if (!button->getActionName().isEmpty() && ifDisplayNames()) { temp = button->getActionName().replace("&", "&&"); DEBUG() << "Name of action for pushed stick button: " << temp << " (Action name was not empty)"; } else { temp = button->getCalculatedActiveZoneSummary().replace("&", "&&"); DEBUG() << "Name of action for pushed stick button: " << temp << " (Action name was empty)"; } } return temp; } void JoyControlStickButtonPushButton::showContextMenu(const QPoint &point) { QPoint globalPos = this->mapToGlobal(point); JoyButtonContextMenu *contextMenu = new JoyButtonContextMenu(button, this); contextMenu->buildMenu(); contextMenu->popup(globalPos); } void JoyControlStickButtonPushButton::tryFlash() { if (button->getButtonState()) { flash(); } } AntiMicroX-antimicrox-b300273/src/joycontrolstickbuttonpushbutton.h000066400000000000000000000032071471077622000257440ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYCONTROLSTICKBUTTONPUSHBUTTON_H #define JOYCONTROLSTICKBUTTONPUSHBUTTON_H #include "flashbuttonwidget.h" class JoyControlStickButton; class QWidget; class JoyControlStickButtonPushButton : public FlashButtonWidget { Q_OBJECT Q_PROPERTY(bool isflashing READ isButtonFlashing) public: explicit JoyControlStickButtonPushButton(JoyControlStickButton *button, bool displayNames, QWidget *parent = nullptr); JoyControlStickButton *getButton(); void setButton(JoyControlStickButton *button); void tryFlash(); protected: virtual QString generateLabel() override; public slots: void disableFlashes() override; void enableFlashes() override; private slots: void showContextMenu(const QPoint &point); private: JoyControlStickButton *button; }; #endif // JOYCONTROLSTICKBUTTONPUSHBUTTON_H AntiMicroX-antimicrox-b300273/src/joycontrolstickcontextmenu.cpp000066400000000000000000000557241471077622000252140ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joycontrolstickcontextmenu.h" #include "antkeymapper.h" #include "common.h" #include "inputdevice.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joycontrolstick.h" #include "mousedialog/mousecontrolsticksettingsdialog.h" #include #include #include #include JoyControlStickContextMenu::JoyControlStickContextMenu(JoyControlStick *stick, QWidget *parent) : QMenu(parent) , helper(stick) { this->stick = stick; getHelperLocal().moveToThread(stick->thread()); connect(this, &JoyControlStickContextMenu::aboutToHide, this, &JoyControlStickContextMenu::deleteLater); } void JoyControlStickContextMenu::buildMenu() { QActionGroup *presetGroup = new QActionGroup(this); int presetMode = 0; int currentPreset = getPresetIndex(); QAction *action = this->addAction(tr("Mouse (Normal)")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action] { setStickPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Mouse (Inverted Horizontal)")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action] { setStickPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Mouse (Inverted Vertical)")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action] { setStickPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Mouse (Inverted Horizontal + Vertical)")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action] { setStickPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Arrows")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action] { setStickPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("Keys: W | A | S | D")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action] { setStickPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("NumPad")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action] { setStickPreset(action); }); presetGroup->addAction(action); presetMode++; action = this->addAction(tr("None")); action->setCheckable(true); action->setChecked(currentPreset == presetMode + 1); action->setData(QVariant(presetMode)); connect(action, &QAction::triggered, this, [this, action] { setStickPreset(action); }); presetGroup->addAction(action); this->addSeparator(); QActionGroup *modesGroup = new QActionGroup(this); int mode = static_cast(JoyControlStick::StandardMode); action = this->addAction(tr("Standard")); action->setCheckable(true); action->setChecked(stick->getJoyMode() == JoyControlStick::StandardMode); action->setData(QVariant(mode)); connect(action, &QAction::triggered, this, [this, action] { setStickMode(action); }); modesGroup->addAction(action); action = this->addAction(tr("Eight Way")); action->setCheckable(true); action->setChecked(stick->getJoyMode() == JoyControlStick::EightWayMode); mode = static_cast(JoyControlStick::EightWayMode); action->setData(QVariant(mode)); connect(action, &QAction::triggered, this, [this, action] { setStickMode(action); }); modesGroup->addAction(action); action = this->addAction(tr("4 Way Cardinal")); action->setCheckable(true); action->setChecked(stick->getJoyMode() == JoyControlStick::FourWayCardinal); mode = static_cast(JoyControlStick::FourWayCardinal); action->setData(QVariant(mode)); connect(action, &QAction::triggered, this, [this, action] { setStickMode(action); }); modesGroup->addAction(action); action = this->addAction(tr("4 Way Diagonal")); action->setCheckable(true); action->setChecked(stick->getJoyMode() == JoyControlStick::FourWayDiagonal); mode = static_cast(JoyControlStick::FourWayDiagonal); action->setData(QVariant(mode)); connect(action, &QAction::triggered, this, [this, action] { setStickMode(action); }); modesGroup->addAction(action); this->addSeparator(); action = this->addAction(tr("Mouse Settings")); action->setCheckable(false); connect(action, &QAction::triggered, this, &JoyControlStickContextMenu::openMouseSettingsDialog); } void JoyControlStickContextMenu::setStickMode(QAction *action) { int item = action->data().toInt(); stick->setJoyMode(static_cast(item)); } void JoyControlStickContextMenu::setStickPreset(QAction *action) { int item = action->data().toInt(); JoyButtonSlot *upButtonSlot = nullptr; JoyButtonSlot *downButtonSlot = nullptr; JoyButtonSlot *leftButtonSlot = nullptr; JoyButtonSlot *rightButtonSlot = nullptr; JoyButtonSlot *upLeftButtonSlot = nullptr; JoyButtonSlot *upRightButtonSlot = nullptr; JoyButtonSlot *downLeftButtonSlot = nullptr; JoyButtonSlot *downRightButtonSlot = nullptr; switch (item) { case 0: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); stick->setJoyMode(JoyControlStick::StandardMode); stick->setDiagonalRange(65); PadderCommon::inputDaemonMutex.unlock(); break; } case 1: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); stick->setJoyMode(JoyControlStick::StandardMode); stick->setDiagonalRange(65); PadderCommon::inputDaemonMutex.unlock(); break; } case 2: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); stick->setJoyMode(JoyControlStick::StandardMode); stick->setDiagonalRange(65); PadderCommon::inputDaemonMutex.unlock(); break; } case 3: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); stick->setJoyMode(JoyControlStick::StandardMode); stick->setDiagonalRange(65); PadderCommon::inputDaemonMutex.unlock(); break; } case 4: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up), Qt::Key_Up, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down), Qt::Key_Down, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left), Qt::Key_Left, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right), Qt::Key_Right, JoyButtonSlot::JoyKeyboard, this); stick->setJoyMode(JoyControlStick::StandardMode); stick->setDiagonalRange(45); PadderCommon::inputDaemonMutex.unlock(); break; } case 5: { PadderCommon::inputDaemonMutex.lock(); upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W), Qt::Key_W, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S), Qt::Key_S, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A), Qt::Key_A, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D), Qt::Key_D, JoyButtonSlot::JoyKeyboard, this); stick->setJoyMode(JoyControlStick::StandardMode); stick->setDiagonalRange(45); PadderCommon::inputDaemonMutex.unlock(); break; } case 6: { PadderCommon::inputDaemonMutex.lock(); if ((stick->getJoyMode() == JoyControlStick::StandardMode) || (stick->getJoyMode() == JoyControlStick::FourWayCardinal)) { upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); } else if (stick->getJoyMode() == JoyControlStick::EightWayMode) { upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); } else if (stick->getJoyMode() == JoyControlStick::FourWayDiagonal) { upLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_7), QtKeyMapperBase::AntKey_KP_7, JoyButtonSlot::JoyKeyboard, this); upRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_9), QtKeyMapperBase::AntKey_KP_9, JoyButtonSlot::JoyKeyboard, this); downLeftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_1), QtKeyMapperBase::AntKey_KP_1, JoyButtonSlot::JoyKeyboard, this); downRightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_3), QtKeyMapperBase::AntKey_KP_3, JoyButtonSlot::JoyKeyboard, this); } stick->setDiagonalRange(45); PadderCommon::inputDaemonMutex.unlock(); break; } case 7: { QMetaObject::invokeMethod(&helper, "clearButtonsSlotsEventReset"); QMetaObject::invokeMethod(stick, "setDiagonalRange", Q_ARG(int, 45)); break; } } QHash tempHash; tempHash.insert(JoyControlStick::StickUp, upButtonSlot); tempHash.insert(JoyControlStick::StickDown, downButtonSlot); tempHash.insert(JoyControlStick::StickLeft, leftButtonSlot); tempHash.insert(JoyControlStick::StickRight, rightButtonSlot); tempHash.insert(JoyControlStick::StickLeftUp, upLeftButtonSlot); tempHash.insert(JoyControlStick::StickRightUp, upRightButtonSlot); tempHash.insert(JoyControlStick::StickLeftDown, downLeftButtonSlot); tempHash.insert(JoyControlStick::StickRightDown, downRightButtonSlot); getHelperLocal().setPendingSlots(&tempHash); QMetaObject::invokeMethod(&helper, "setFromPendingSlots", Qt::BlockingQueuedConnection); } int JoyControlStickContextMenu::getPresetIndex() { int result = 0; PadderCommon::inputDaemonMutex.lock(); JoyControlStickButton *upButton = stick->getDirectionButton(JoyControlStick::StickUp); QList *upslots = upButton->getAssignedSlots(); JoyControlStickButton *downButton = stick->getDirectionButton(JoyControlStick::StickDown); QList *downslots = downButton->getAssignedSlots(); JoyControlStickButton *leftButton = stick->getDirectionButton(JoyControlStick::StickLeft); QList *leftslots = leftButton->getAssignedSlots(); JoyControlStickButton *rightButton = stick->getDirectionButton(JoyControlStick::StickRight); QList *rightslots = rightButton->getAssignedSlots(); if ((upslots->length() == 1) && (downslots->length() == 1) && (leftslots->length() == 1) && (rightslots->length() == 1)) { JoyButtonSlot *upslot = upslots->at(0); JoyButtonSlot *downslot = downslots->at(0); JoyButtonSlot *leftslot = leftslots->at(0); JoyButtonSlot *rightslot = rightslots->at(0); if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseUp) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseDown) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseRight)) { result = 1; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseUp) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseDown) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseRight) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { result = 2; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseDown) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseUp) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseRight)) { result = 3; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseDown) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseUp) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseRight) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { result = 4; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right))) { result = 5; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D))) { result = 6; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6))) { result = 7; } } else if ((upslots->length() == 0) && (downslots->length() == 0) && (leftslots->length() == 0) && (rightslots->length() == 0)) { result = 8; } PadderCommon::inputDaemonMutex.unlock(); return result; } void JoyControlStickContextMenu::openMouseSettingsDialog() { MouseControlStickSettingsDialog *dialog = new MouseControlStickSettingsDialog(stick, parentWidget()); dialog->show(); } JoyControlStickContextMenuHelper &JoyControlStickContextMenu::getHelperLocal() { return helper; } AntiMicroX-antimicrox-b300273/src/joycontrolstickcontextmenu.h000066400000000000000000000031531471077622000246460ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYCONTROLSTICKCONTEXTMENU_H #define JOYCONTROLSTICKCONTEXTMENU_H #include "uihelpers/joycontrolstickcontextmenuhelper.h" #include class JoyControlStick; class QWidget; /** * @brief The control stick context menu widget used by StickPushButtonGroup */ class JoyControlStickContextMenu : public QMenu { Q_OBJECT public: explicit JoyControlStickContextMenu(JoyControlStick *stick, QWidget *parent = nullptr); void buildMenu(); protected: int getPresetIndex(); private slots: void setStickPreset(QAction *action); void setStickMode(QAction *action); void openMouseSettingsDialog(); private: JoyControlStickContextMenuHelper &getHelperLocal(); JoyControlStick *stick; JoyControlStickContextMenuHelper helper; }; #endif // JOYCONTROLSTICKCONTEXTMENU_H AntiMicroX-antimicrox-b300273/src/joycontrolstickdirectionstype.h000066400000000000000000000023441471077622000253430ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYCONTROLSTICKDIRECTIONSTYPE_H #define JOYCONTROLSTICKDIRECTIONSTYPE_H class JoyStickDirectionsType { public: enum JoyStickDirections { StickCentered = 0, StickUp = 1, StickRight = 3, StickDown = 5, StickLeft = 7, StickRightUp = 2, StickRightDown = 4, StickLeftUp = 8, StickLeftDown = 6 }; }; #endif // JOYCONTROLSTICKDIRECTIONSTYPE_H AntiMicroX-antimicrox-b300273/src/joycontrolstickpushbutton.cpp000066400000000000000000000061761471077622000250530ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joycontrolstickpushbutton.h" #include "joycontrolstick.h" #include "joycontrolstickcontextmenu.h" #include JoyControlStickPushButton::JoyControlStickPushButton(JoyControlStick *stick, bool displayNames, QWidget *parent) : FlashButtonWidget(displayNames, parent) { this->stick = stick; refreshLabel(); tryFlash(); this->setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &JoyControlStickPushButton::customContextMenuRequested, this, &JoyControlStickPushButton::showContextMenu); connect(stick, &JoyControlStick::active, this, &JoyControlStickPushButton::flash, Qt::QueuedConnection); connect(stick, &JoyControlStick::released, this, &JoyControlStickPushButton::unflash, Qt::QueuedConnection); connect(stick, &JoyControlStick::stickNameChanged, this, &JoyControlStickPushButton::refreshLabel); } JoyControlStick *JoyControlStickPushButton::getStick() const { return stick; } /** * @brief Generate the string that will be displayed on the button * @return Display string */ QString JoyControlStickPushButton::generateLabel() { QString temp = QString(); if (!stick->getStickName().isEmpty() && ifDisplayNames()) { temp.append(stick->getPartialName(false, true)); } else { temp.append(stick->getPartialName(false)); } qDebug() << "Name of joy control stick push button: " << temp; return temp; } void JoyControlStickPushButton::disableFlashes() { disconnect(stick, &JoyControlStick::active, this, &JoyControlStickPushButton::flash); disconnect(stick, &JoyControlStick::released, this, &JoyControlStickPushButton::unflash); this->unflash(); } void JoyControlStickPushButton::enableFlashes() { connect(stick, &JoyControlStick::active, this, &JoyControlStickPushButton::flash, Qt::QueuedConnection); connect(stick, &JoyControlStick::released, this, &JoyControlStickPushButton::unflash, Qt::QueuedConnection); } void JoyControlStickPushButton::showContextMenu(const QPoint &point) { QPoint globalPos = this->mapToGlobal(point); JoyControlStickContextMenu *contextMenu = new JoyControlStickContextMenu(stick, this); contextMenu->buildMenu(); contextMenu->popup(globalPos); } void JoyControlStickPushButton::tryFlash() { if (stick->getCurrentDirection() != JoyControlStick::StickCentered) { flash(); } } AntiMicroX-antimicrox-b300273/src/joycontrolstickpushbutton.h000066400000000000000000000027531471077622000245150ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYCONTROLSTICKPUSHBUTTON_H #define JOYCONTROLSTICKPUSHBUTTON_H #include "flashbuttonwidget.h" class JoyControlStick; class QWidget; class JoyControlStickPushButton : public FlashButtonWidget { Q_OBJECT public: explicit JoyControlStickPushButton(JoyControlStick *stick, bool displayNames, QWidget *parent = nullptr); JoyControlStick *getStick() const; void tryFlash(); protected: virtual QString generateLabel() override; public slots: void disableFlashes() override; void enableFlashes() override; private slots: void showContextMenu(const QPoint &point); private: JoyControlStick *stick; }; #endif // JOYCONTROLSTICKPUSHBUTTON_H AntiMicroX-antimicrox-b300273/src/joycontrolstickstatusbox.cpp000066400000000000000000000564341471077622000246760ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joycontrolstickstatusbox.h" #include "common.h" #include "globalvariables.h" #include "joyaxis.h" #include "joycontrolstick.h" #include #include #include #include #include #include #include #include JoyControlStickStatusBox::JoyControlStickStatusBox(QWidget *parent) : QWidget(parent) , m_stick(nullptr) { } JoyControlStickStatusBox::JoyControlStickStatusBox(JoyControlStick *stick, QWidget *parent) : QWidget(parent) , m_stick(nullptr) { setStick(stick); } void JoyControlStickStatusBox::setStick(JoyControlStick *stick) { if (m_stick != nullptr) { disconnect(stick, SIGNAL(deadZoneChanged(int)), this, nullptr); disconnect(stick, SIGNAL(moved(int, int)), this, nullptr); disconnect(stick, SIGNAL(diagonalRangeChanged(int)), this, nullptr); disconnect(stick, SIGNAL(maxZoneChanged(int)), this, nullptr); disconnect(stick, SIGNAL(modifierZoneChanged(int)), this, nullptr); disconnect(stick, SIGNAL(joyModeChanged()), this, nullptr); disconnect(stick, SIGNAL(circleAdjustChange(double)), this, nullptr); } m_stick = stick; connect(stick, SIGNAL(deadZoneChanged(int)), this, SLOT(update())); connect(stick, SIGNAL(moved(int, int)), this, SLOT(update())); connect(stick, SIGNAL(diagonalRangeChanged(int)), this, SLOT(update())); connect(stick, SIGNAL(maxZoneChanged(int)), this, SLOT(update())); connect(stick, SIGNAL(modifierZoneChanged(int)), this, SLOT(update())); connect(stick, SIGNAL(joyModeChanged()), this, SLOT(update())); connect(stick, SIGNAL(circleAdjustChange(double)), this, SLOT(update())); update(); } JoyControlStick *JoyControlStickStatusBox::getStick() const { return m_stick; } int JoyControlStickStatusBox::heightForWidth(int width) const { return width; } QSize JoyControlStickStatusBox::sizeHint() const { return QSize(-1, -1); } void JoyControlStickStatusBox::paintEvent(QPaintEvent *event) { Q_UNUSED(event); PadderCommon::inputDaemonMutex.lock(); if (m_stick == nullptr || m_stick->getJoyMode() == JoyControlStick::StandardMode || m_stick->getJoyMode() == JoyControlStick::EightWayMode) { drawEightWayBox(); } else if (m_stick->getJoyMode() == JoyControlStick::FourWayCardinal) { drawFourWayCardinalBox(); } else if (m_stick->getJoyMode() == JoyControlStick::FourWayDiagonal) { drawFourWayDiagonalBox(); } PadderCommon::inputDaemonMutex.unlock(); } void JoyControlStickStatusBox::drawEightWayBox() { QPainter paint(this); paint.setRenderHint(QPainter::Antialiasing, true); int side = qMin(width() - 2, height() - 2); QPixmap pix(side, side); pix.fill(Qt::transparent); QPainter painter(&pix); painter.setRenderHint(QPainter::Antialiasing, true); // Draw outline circle QPen penny; penny.setColor(Qt::black); penny.setWidth(0); painter.setPen(penny); painter.setBrush(Qt::NoBrush); painter.save(); painter.scale(side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0), side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0)); painter.translate(GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX); painter.drawEllipse(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2); // Draw diagonal zones if (m_stick != nullptr) { QList anglesList = m_stick->getDiagonalZoneAngles(); int diagonalRange = m_stick->getDiagonalRange(); penny.setWidth(0); penny.setColor(Qt::black); painter.setPen(penny); painter.setBrush(QBrush(Qt::green)); painter.drawPie(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2, static_cast(anglesList.value(2)) * 16, diagonalRange * 16); painter.drawPie(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2, static_cast(anglesList.value(4)) * 16, diagonalRange * 16); painter.drawPie(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2, static_cast(anglesList.value(6)) * 16, diagonalRange * 16); painter.drawPie(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2, static_cast(anglesList.value(8)) * 16, diagonalRange * 16); // Draw modifier zone circle int modifierZone = m_stick->getModifierZone(); int maxZone = m_stick->getMaxZone(); penny.setWidth(0); penny.setColor(Qt::blue); painter.setOpacity(0.5); painter.setPen(penny); painter.setBrush(QBrush(Qt::yellow)); if (m_stick->getModifierZoneInverted()) { painter.drawEllipse(-modifierZone, -modifierZone, modifierZone * 2, modifierZone * 2); } else { QPainterPath modifierZonePath; modifierZonePath.addEllipse(QPoint(0, 0), maxZone, maxZone); modifierZonePath.addEllipse(QPoint(0, 0), modifierZone, modifierZone); painter.drawPath(modifierZonePath); } } // Draw deadzone circle penny.setWidth(0); penny.setColor(Qt::blue); painter.setOpacity(1); painter.setPen(penny); painter.setBrush(QBrush(Qt::red)); int deadZone = m_stick != nullptr ? m_stick->getDeadZone() : 0; painter.drawEllipse(-deadZone, -deadZone, deadZone * 2, deadZone * 2); painter.restore(); painter.save(); penny.setWidth(0); penny.setColor(Qt::gray); painter.setPen(penny); painter.scale(side / 2.0, side / 2.0); painter.translate(1, 1); // Draw Y line painter.drawLine(0, -1, 0, 1); // Draw X line painter.drawLine(-1, 0, 1, 0); painter.restore(); painter.save(); painter.scale(side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0), side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0)); painter.translate(GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX); penny.setWidth(0); painter.setBrush(QBrush(Qt::black)); penny.setColor(Qt::black); painter.setPen(penny); if (m_stick != nullptr) { // Draw raw crosshair int linexstart = m_stick->getXCoordinate() - 1000; int lineystart = m_stick->getYCoordinate() - 1000; if (linexstart < GlobalVariables::JoyAxis::AXISMIN) linexstart = GlobalVariables::JoyAxis::AXISMIN; if (lineystart < GlobalVariables::JoyAxis::AXISMIN) lineystart = GlobalVariables::JoyAxis::AXISMIN; painter.drawRect(linexstart, lineystart, 2000, 2000); painter.setBrush(QBrush(Qt::darkBlue)); penny.setColor(Qt::darkBlue); painter.setPen(penny); // Draw adjusted crosshair linexstart = m_stick->getCircleXCoordinate() - 1000; lineystart = m_stick->getCircleYCoordinate() - 1000; if (linexstart < GlobalVariables::JoyAxis::AXISMIN) linexstart = GlobalVariables::JoyAxis::AXISMIN; if (lineystart < GlobalVariables::JoyAxis::AXISMIN) lineystart = GlobalVariables::JoyAxis::AXISMIN; painter.drawRect(linexstart, lineystart, 2000, 2000); } // Reset pen painter.restore(); penny.setColor(Qt::black); painter.setPen(penny); // Draw primary pixmap painter.setCompositionMode(QPainter::CompositionMode_DestinationOver); painter.setPen(Qt::NoPen); painter.fillRect(0, 0, side, side, palette().window().color()); paint.drawPixmap(pix.rect(), pix); paint.save(); paint.scale(side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0), side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0)); paint.translate(GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX); // Draw max zone and initial inner clear circle int maxzone = m_stick != nullptr ? m_stick->getMaxZone() : GlobalVariables::JoyControlStick::DEFAULTMAXZONE; int diffmaxzone = GlobalVariables::JoyAxis::AXISMAX - maxzone; paint.setOpacity(0.5); paint.setBrush(Qt::darkGreen); paint.drawEllipse(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2); paint.setCompositionMode(QPainter::CompositionMode_Clear); paint.setPen(Qt::NoPen); paint.drawEllipse(-GlobalVariables::JoyAxis::AXISMAX + diffmaxzone, -GlobalVariables::JoyAxis::AXISMAX + diffmaxzone, GlobalVariables::JoyAxis::AXISMAX * 2 - (diffmaxzone * 2), GlobalVariables::JoyAxis::AXISMAX * 2 - (diffmaxzone * 2)); painter.setCompositionMode(QPainter::CompositionMode_SourceOver); paint.setOpacity(1.0); paint.restore(); // Re-draw pixmap so the inner circle will be transparent paint.setCompositionMode(QPainter::CompositionMode_DestinationOver); paint.drawPixmap(pix.rect(), pix); paint.setCompositionMode(QPainter::CompositionMode_SourceOver); } void JoyControlStickStatusBox::drawFourWayCardinalBox() { QPainter paint(this); paint.setRenderHint(QPainter::Antialiasing, true); int side = qMin(width() - 2, height() - 2); QPixmap pix(side, side); pix.fill(Qt::transparent); QPainter painter(&pix); painter.setRenderHint(QPainter::Antialiasing, true); // Draw outline circle QPen penny; penny.setColor(Qt::black); penny.setWidth(0); painter.setPen(penny); painter.setBrush(Qt::NoBrush); painter.save(); painter.scale(side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0), side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0)); painter.translate(GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX); painter.drawEllipse(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2); if (m_stick != nullptr) { // Draw diagonal zones QList anglesList = m_stick->getFourWayCardinalZoneAngles(); penny.setWidth(0); penny.setColor(Qt::black); painter.setPen(penny); painter.setOpacity(0.25); painter.setBrush(QBrush(Qt::black)); painter.drawPie(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2, anglesList.value(1) * 16, 90 * 16); painter.drawPie(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2, anglesList.value(3) * 16, 90 * 16); painter.setOpacity(1.0); // Draw modifier zone circle int modifierZone = m_stick->getModifierZone(); int maxZone = m_stick->getMaxZone(); penny.setWidth(0); penny.setColor(Qt::blue); painter.setOpacity(0.5); painter.setPen(penny); painter.setBrush(QBrush(Qt::yellow)); if (m_stick->getModifierZoneInverted()) { painter.drawEllipse(-modifierZone, -modifierZone, modifierZone * 2, modifierZone * 2); } else { QPainterPath modifierZonePath; modifierZonePath.addEllipse(QPoint(0, 0), maxZone, maxZone); modifierZonePath.addEllipse(QPoint(0, 0), modifierZone, modifierZone); painter.drawPath(modifierZonePath); } } // Draw deadzone circle penny.setWidth(0); penny.setColor(Qt::blue); painter.setPen(penny); painter.setBrush(QBrush(Qt::red)); int deadZone = m_stick != nullptr ? m_stick->getDeadZone() : 0; painter.drawEllipse(-deadZone, -deadZone, deadZone * 2, deadZone * 2); painter.restore(); painter.save(); penny.setWidth(0); penny.setColor(Qt::black); painter.setPen(penny); painter.setOpacity(0.5); painter.scale(side / 2.0, side / 2.0); painter.translate(1, 1); // Draw Y line painter.drawLine(0, -1, 0, 1); // Draw X line painter.drawLine(-1, 0, 1, 0); painter.setOpacity(1.0); painter.restore(); painter.save(); painter.scale(side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0), side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0)); painter.translate(GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX); penny.setWidth(0); painter.setBrush(QBrush(Qt::black)); penny.setColor(Qt::black); painter.setPen(penny); if (m_stick != nullptr) { // Draw raw crosshair int linexstart = m_stick->getXCoordinate() - 1000; int lineystart = m_stick->getYCoordinate() - 1000; if (linexstart < GlobalVariables::JoyAxis::AXISMIN) linexstart = GlobalVariables::JoyAxis::AXISMIN; if (lineystart < GlobalVariables::JoyAxis::AXISMIN) lineystart = GlobalVariables::JoyAxis::AXISMIN; painter.drawRect(linexstart, lineystart, 2000, 2000); painter.setBrush(QBrush(Qt::darkBlue)); penny.setColor(Qt::darkBlue); painter.setPen(penny); // Draw adjusted crosshair linexstart = m_stick->getCircleXCoordinate() - 1000; lineystart = m_stick->getCircleYCoordinate() - 1000; if (linexstart < GlobalVariables::JoyAxis::AXISMIN) linexstart = GlobalVariables::JoyAxis::AXISMIN; if (lineystart < GlobalVariables::JoyAxis::AXISMIN) lineystart = GlobalVariables::JoyAxis::AXISMIN; painter.drawRect(linexstart, lineystart, 2000, 2000); } // Reset pen painter.restore(); penny.setColor(Qt::black); painter.setPen(penny); // Draw primary pixmap painter.setCompositionMode(QPainter::CompositionMode_DestinationOver); painter.setPen(Qt::NoPen); painter.fillRect(0, 0, side, side, palette().window().color()); paint.drawPixmap(pix.rect(), pix); paint.save(); paint.scale(side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0), side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0)); paint.translate(GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX); // Draw max zone and initial inner clear circle int maxzone = m_stick != nullptr ? m_stick->getMaxZone() : GlobalVariables::JoyControlStick::DEFAULTMAXZONE; int diffmaxzone = GlobalVariables::JoyAxis::AXISMAX - maxzone; paint.setOpacity(0.5); paint.setBrush(Qt::darkGreen); paint.drawEllipse(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2); paint.setCompositionMode(QPainter::CompositionMode_Clear); paint.setPen(Qt::NoPen); paint.drawEllipse(-GlobalVariables::JoyAxis::AXISMAX + diffmaxzone, -GlobalVariables::JoyAxis::AXISMAX + diffmaxzone, GlobalVariables::JoyAxis::AXISMAX * 2 - (diffmaxzone * 2), GlobalVariables::JoyAxis::AXISMAX * 2 - (diffmaxzone * 2)); painter.setCompositionMode(QPainter::CompositionMode_SourceOver); paint.setOpacity(1.0); paint.restore(); // Re-draw pixmap so the inner circle will be transparent paint.setCompositionMode(QPainter::CompositionMode_DestinationOver); paint.drawPixmap(pix.rect(), pix); paint.setCompositionMode(QPainter::CompositionMode_SourceOver); } void JoyControlStickStatusBox::drawFourWayDiagonalBox() { QPainter paint(this); paint.setRenderHint(QPainter::Antialiasing, true); int side = qMin(width() - 2, height() - 2); QPixmap pix(side, side); pix.fill(Qt::transparent); QPainter painter(&pix); painter.setRenderHint(QPainter::Antialiasing, true); // Draw outline circle QPen penny; penny.setColor(Qt::black); penny.setWidth(0); painter.setPen(penny); painter.setBrush(Qt::NoBrush); painter.save(); painter.scale(side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0), side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0)); painter.translate(GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX); painter.drawEllipse(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2); if (m_stick != nullptr) { // Draw diagonal zones QList anglesList = m_stick->getFourWayDiagonalZoneAngles(); penny.setWidth(0); penny.setColor(Qt::black); painter.setPen(penny); painter.setBrush(QBrush(Qt::black)); painter.setOpacity(0.25); painter.drawPie(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2, anglesList.value(1) * 16, 90 * 16); painter.drawPie(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2, anglesList.value(3) * 16, 90 * 16); painter.setOpacity(1.0); // Draw modifier zone circle int modifierZone = m_stick->getModifierZone(); int maxZone = m_stick->getMaxZone(); penny.setWidth(0); penny.setColor(Qt::blue); painter.setOpacity(0.5); painter.setPen(penny); painter.setBrush(QBrush(Qt::yellow)); if (m_stick->getModifierZoneInverted()) { painter.drawEllipse(-modifierZone, -modifierZone, modifierZone * 2, modifierZone * 2); } else { QPainterPath modifierZonePath; modifierZonePath.addEllipse(QPoint(0, 0), maxZone, maxZone); modifierZonePath.addEllipse(QPoint(0, 0), modifierZone, modifierZone); painter.drawPath(modifierZonePath); } } // Draw deadzone circle penny.setWidth(0); penny.setColor(Qt::blue); painter.setPen(penny); painter.setBrush(QBrush(Qt::red)); int deadZone = m_stick != nullptr ? m_stick->getDeadZone() : 0; painter.drawEllipse(-deadZone, -deadZone, deadZone * 2, deadZone * 2); painter.restore(); painter.save(); penny.setWidth(0); penny.setColor(Qt::black); painter.setOpacity(0.5); painter.setPen(penny); painter.scale(side / 2.0, side / 2.0); painter.translate(1, 1); // Draw Y line painter.drawLine(0, -1, 0, 1); // Draw X line painter.drawLine(-1, 0, 1, 0); painter.setOpacity(1.0); painter.restore(); painter.save(); painter.scale(side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0), side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0)); painter.translate(GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX); penny.setWidth(0); painter.setBrush(QBrush(Qt::black)); penny.setColor(Qt::black); painter.setPen(penny); // Draw raw crosshair if (m_stick != nullptr) { int linexstart = m_stick->getXCoordinate() - 1000; int lineystart = m_stick->getYCoordinate() - 1000; if (linexstart < GlobalVariables::JoyAxis::AXISMIN) linexstart = GlobalVariables::JoyAxis::AXISMIN; if (lineystart < GlobalVariables::JoyAxis::AXISMIN) lineystart = GlobalVariables::JoyAxis::AXISMIN; painter.drawRect(linexstart, lineystart, 2000, 2000); painter.setBrush(QBrush(Qt::darkBlue)); penny.setColor(Qt::darkBlue); painter.setPen(penny); // Draw adjusted crosshair linexstart = m_stick->getCircleXCoordinate() - 1000; lineystart = m_stick->getCircleYCoordinate() - 1000; if (linexstart < GlobalVariables::JoyAxis::AXISMIN) linexstart = GlobalVariables::JoyAxis::AXISMIN; if (lineystart < GlobalVariables::JoyAxis::AXISMIN) lineystart = GlobalVariables::JoyAxis::AXISMIN; painter.drawRect(linexstart, lineystart, 2000, 2000); } // Reset pen painter.restore(); penny.setColor(Qt::black); painter.setPen(penny); // Draw primary pixmap painter.setCompositionMode(QPainter::CompositionMode_DestinationOver); painter.setPen(Qt::NoPen); painter.fillRect(0, 0, side, side, palette().window().color()); paint.drawPixmap(pix.rect(), pix); paint.save(); paint.scale(side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0), side / static_cast(GlobalVariables::JoyAxis::AXISMAX * 2.0)); paint.translate(GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX); // Draw max zone and initial inner clear circle int maxzone = m_stick != nullptr ? m_stick->getMaxZone() : GlobalVariables::JoyControlStick::DEFAULTMAXZONE; int diffmaxzone = GlobalVariables::JoyAxis::AXISMAX - maxzone; paint.setOpacity(0.5); paint.setBrush(Qt::darkGreen); paint.drawEllipse(-GlobalVariables::JoyAxis::AXISMAX, -GlobalVariables::JoyAxis::AXISMAX, GlobalVariables::JoyAxis::AXISMAX * 2, GlobalVariables::JoyAxis::AXISMAX * 2); paint.setCompositionMode(QPainter::CompositionMode_Clear); paint.setPen(Qt::NoPen); paint.drawEllipse(-GlobalVariables::JoyAxis::AXISMAX + diffmaxzone, -GlobalVariables::JoyAxis::AXISMAX + diffmaxzone, GlobalVariables::JoyAxis::AXISMAX * 2 - (diffmaxzone * 2), GlobalVariables::JoyAxis::AXISMAX * 2 - (diffmaxzone * 2)); painter.setCompositionMode(QPainter::CompositionMode_SourceOver); paint.setOpacity(1.0); paint.restore(); // Re-draw pixmap so the inner circle will be transparent paint.setCompositionMode(QPainter::CompositionMode_DestinationOver); paint.drawPixmap(pix.rect(), pix); paint.setCompositionMode(QPainter::CompositionMode_SourceOver); } AntiMicroX-antimicrox-b300273/src/joycontrolstickstatusbox.h000066400000000000000000000031071471077622000243300ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYCONTROLSTICKSTATUSBOX_H #define JOYCONTROLSTICKSTATUSBOX_H #include #include class JoyControlStick; class QPaintEvent; class JoyControlStickStatusBox : public QWidget { Q_OBJECT public: explicit JoyControlStickStatusBox(QWidget *parent = nullptr); explicit JoyControlStickStatusBox(JoyControlStick *stick, QWidget *parent = nullptr); void setStick(JoyControlStick *stick); JoyControlStick *getStick() const; virtual int heightForWidth(int width) const; QSize sizeHint() const; protected: virtual void paintEvent(QPaintEvent *event); void drawEightWayBox(); void drawFourWayCardinalBox(); void drawFourWayDiagonalBox(); private: JoyControlStick *m_stick; }; #endif // JOYCONTROLSTICKSTATUSBOX_H AntiMicroX-antimicrox-b300273/src/joydpad.cpp000066400000000000000000000777471471077622000211250ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joydpad.h" #include "globalvariables.h" #include "inputdevice.h" #include #include JoyDPad::JoyDPad(int index, int originset, SetJoystick *parentSet, QObject *parent) : QObject(parent) { m_index = index; buttons = QHash(); activeDiagonalButton = nullptr; prevDirection = JoyDPadButton::DpadCentered; pendingDirection = prevDirection; m_originset = originset; currentMode = StandardMode; m_parentSet = parentSet; this->dpadDelay = GlobalVariables::JoyDPad::DEFAULTDPADDELAY; populateButtons(); pendingEvent = false; pendingEventDirection = prevDirection; pendingIgnoreSets = false; directionDelayTimer.setSingleShot(true); connect(&directionDelayTimer, &QTimer::timeout, this, &JoyDPad::dpadDirectionChangeEvent); } JoyDPadButton *JoyDPad::getJoyButton(int index_local) { return buttons.value(index_local); } void JoyDPad::populateButtons() { JoyDPadButton *button = new JoyDPadButton(JoyDPadButton::DpadUp, m_originset, this, m_parentSet, this); buttons.insert(JoyDPadButton::DpadUp, button); button = new JoyDPadButton(JoyDPadButton::DpadDown, m_originset, this, m_parentSet, this); buttons.insert(JoyDPadButton::DpadDown, button); button = new JoyDPadButton(JoyDPadButton::DpadRight, m_originset, this, m_parentSet, this); buttons.insert(JoyDPadButton::DpadRight, button); button = new JoyDPadButton(JoyDPadButton::DpadLeft, m_originset, this, m_parentSet, this); buttons.insert(JoyDPadButton::DpadLeft, button); button = new JoyDPadButton(JoyDPadButton::DpadLeftUp, m_originset, this, m_parentSet, this); buttons.insert(JoyDPadButton::DpadLeftUp, button); button = new JoyDPadButton(JoyDPadButton::DpadRightUp, m_originset, this, m_parentSet, this); buttons.insert(JoyDPadButton::DpadRightUp, button); button = new JoyDPadButton(JoyDPadButton::DpadRightDown, m_originset, this, m_parentSet, this); buttons.insert(JoyDPadButton::DpadRightDown, button); button = new JoyDPadButton(JoyDPadButton::DpadLeftDown, m_originset, this, m_parentSet, this); buttons.insert(JoyDPadButton::DpadLeftDown, button); } QString JoyDPad::getName(bool fullForceFormat, bool displayNames) { QString label = QString(); if (!dpadName.isEmpty() && displayNames) { if (fullForceFormat) { label.append(tr("DPad")).append(" "); } label.append(dpadName); } else if (!defaultDPadName.isEmpty()) { if (fullForceFormat) { label.append(tr("DPad")).append(" "); } label.append(defaultDPadName); } else { label.append(tr("DPad")).append(" "); label.append(QString::number(getRealJoyNumber())); } return label; } int JoyDPad::getJoyNumber() { return m_index; } int JoyDPad::getIndex() { return m_index; } int JoyDPad::getRealJoyNumber() { return m_index + 1; } QString JoyDPad::getXmlName() { return GlobalVariables::JoyDPad::xmlName; } void JoyDPad::queuePendingEvent(int value, bool ignoresets) { pendingEvent = true; pendingEventDirection = value; pendingIgnoreSets = ignoresets; } void JoyDPad::activatePendingEvent() { if (pendingEvent) { joyEvent(pendingEventDirection, pendingIgnoreSets); pendingEvent = false; pendingEventDirection = static_cast(JoyDPadButton::DpadCentered); pendingIgnoreSets = false; } } bool JoyDPad::hasPendingEvent() { return pendingEvent; } void JoyDPad::clearPendingEvent() { pendingEvent = false; pendingEventDirection = static_cast(JoyDPadButton::DpadCentered); pendingIgnoreSets = false; } void JoyDPad::joyEvent(int value, bool ignoresets) { if (value != static_cast(pendingDirection)) { if (value != static_cast(JoyDPadButton::DpadCentered)) { if (prevDirection == JoyDPadButton::DpadCentered) { emit active(value); } pendingDirection = static_cast(value); if (ignoresets || (dpadDelay == 0)) { if (directionDelayTimer.isActive()) { directionDelayTimer.stop(); } createDeskEvent(ignoresets); } else if (pendingDirection != prevDirection) { if (!directionDelayTimer.isActive()) { directionDelayTimer.start(dpadDelay); } } else { if (directionDelayTimer.isActive()) { directionDelayTimer.stop(); } } } else { emit released(value); pendingDirection = JoyDPadButton::DpadCentered; if (ignoresets || dpadDelay == 0) { if (directionDelayTimer.isActive()) { directionDelayTimer.stop(); } createDeskEvent(ignoresets); } else { if (!directionDelayTimer.isActive()) { directionDelayTimer.start(dpadDelay); } } } } } QHash *JoyDPad::getJoyButtons() { return &buttons; } int JoyDPad::getCurrentDirection() { return prevDirection; } void JoyDPad::setJoyMode(JoyMode mode) { currentMode = mode; emit joyModeChanged(); emit propertyUpdated(); } JoyDPad::JoyMode JoyDPad::getJoyMode() { return currentMode; } void JoyDPad::releaseButtonEvents() { QHashIterator iter(buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->joyEvent(false, true); } } QHash *JoyDPad::getButtons() { return &buttons; } bool JoyDPad::isDefault() { bool value = true; value = value && (currentMode == StandardMode); value = value && (dpadDelay == GlobalVariables::JoyDPad::DEFAULTDPADDELAY); QHashIterator iter(buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); value = value && (button->isDefault()); } return value; } void JoyDPad::setButtonsMouseMode(JoyButton::JoyMouseMovementMode mode) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setMouseMode(mode); } } bool JoyDPad::hasSameButtonsMouseMode() { bool result = true; JoyButton::JoyMouseMovementMode initialMode = JoyButton::MouseCursor; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyDPadButton *button = iter.value(); initialMode = button->getMouseMode(); while (++iter != temphash.cend()) { button = iter.value(); JoyButton::JoyMouseMovementMode temp = button->getMouseMode(); if (temp != initialMode) { result = false; break; } } return result; } JoyButton::JoyMouseMovementMode JoyDPad::getButtonsPresetMouseMode() { JoyButton::JoyMouseMovementMode resultMode = JoyButton::MouseCursor; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return resultMode; JoyDPadButton *button = iter.value(); resultMode = button->getMouseMode(); while (++iter != temphash.cend()) { button = iter.value(); JoyButton::JoyMouseMovementMode temp = button->getMouseMode(); if (temp != resultMode) { resultMode = JoyButton::MouseCursor; break; } } return resultMode; } void JoyDPad::setButtonsMouseCurve(JoyButton::JoyMouseCurve mouseCurve) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setMouseCurve(mouseCurve); } } bool JoyDPad::hasSameButtonsMouseCurve() { bool result = true; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyDPadButton *button = iter.value(); JoyButton::JoyMouseCurve initialCurve = button->getMouseCurve(); while (++iter != temphash.cend()) { button = iter.value(); JoyButton::JoyMouseCurve temp = button->getMouseCurve(); if (temp != initialCurve) { result = false; break; } } return result; } JoyButton::JoyMouseCurve JoyDPad::getButtonsPresetMouseCurve() { JoyButton::JoyMouseCurve resultCurve = JoyButton::LinearCurve; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return resultCurve; JoyDPadButton *button = iter.value(); resultCurve = button->getMouseCurve(); while (++iter != temphash.cend()) { button = iter.value(); JoyButton::JoyMouseCurve temp = button->getMouseCurve(); if (temp != resultCurve) { resultCurve = JoyButton::LinearCurve; break; } } return resultCurve; } void JoyDPad::setButtonsSpringWidth(int value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setSpringWidth(value); } } void JoyDPad::setButtonsSpringHeight(int value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setSpringHeight(value); } } int JoyDPad::getButtonsPresetSpringWidth() { int presetSpringWidth = 0; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return presetSpringWidth; JoyDPadButton *button = iter.value(); presetSpringWidth = button->getSpringWidth(); while (++iter != temphash.cend()) { button = iter.value(); int temp = button->getSpringWidth(); if (temp != presetSpringWidth) { presetSpringWidth = 0; break; } } return presetSpringWidth; } int JoyDPad::getButtonsPresetSpringHeight() { int presetSpringHeight = 0; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return presetSpringHeight; JoyDPadButton *button = iter.value(); presetSpringHeight = button->getSpringHeight(); while (++iter != temphash.cend()) { button = iter.value(); int temp = button->getSpringHeight(); if (temp != presetSpringHeight) { presetSpringHeight = 0; break; } } return presetSpringHeight; } void JoyDPad::setButtonsSensitivity(double value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setSensitivity(value); } } double JoyDPad::getButtonsPresetSensitivity() { double presetSensitivity = 1.0; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return presetSensitivity; JoyDPadButton *button = iter.value(); presetSensitivity = button->getSensitivity(); while (++iter != temphash.cend()) { button = iter.value(); double temp = button->getSensitivity(); if (!qFuzzyCompare(temp, presetSensitivity)) { presetSensitivity = 1.0; break; } } return presetSensitivity; } QHash JoyDPad::getApplicableButtons() { QHash temphash; if ((currentMode == StandardMode) || (currentMode == EightWayMode) || (currentMode == FourWayCardinal)) { temphash.insert(JoyDPadButton::DpadUp, buttons.value(JoyDPadButton::DpadUp)); temphash.insert(JoyDPadButton::DpadDown, buttons.value(JoyDPadButton::DpadDown)); temphash.insert(JoyDPadButton::DpadLeft, buttons.value(JoyDPadButton::DpadLeft)); temphash.insert(JoyDPadButton::DpadRight, buttons.value(JoyDPadButton::DpadRight)); } if ((currentMode == EightWayMode) || (currentMode == FourWayDiagonal)) { temphash.insert(JoyDPadButton::DpadLeftUp, buttons.value(JoyDPadButton::DpadLeftUp)); temphash.insert(JoyDPadButton::DpadRightUp, buttons.value(JoyDPadButton::DpadRightUp)); temphash.insert(JoyDPadButton::DpadRightDown, buttons.value(JoyDPadButton::DpadRightDown)); temphash.insert(JoyDPadButton::DpadLeftDown, buttons.value(JoyDPadButton::DpadLeftDown)); } return temphash; } void JoyDPad::setDPadName(QString tempName) { if ((tempName.length() <= 20) && (tempName != dpadName)) { dpadName = tempName; emit dpadNameChanged(); emit propertyUpdated(); } } const QString JoyDPad::getDpadName() { return dpadName; } const QString JoyDPad::getDefaultDpadName() { return defaultDPadName; } void JoyDPad::setButtonsWheelSpeedX(int value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setWheelSpeed(value, 'X'); } } void JoyDPad::setButtonsWheelSpeedY(int value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setWheelSpeed(value, 'Y'); } } void JoyDPad::setDefaultDPadName(QString tempname) { defaultDPadName = tempname; emit dpadNameChanged(); } QString JoyDPad::getDefaultDPadName() { return defaultDPadName; } SetJoystick *JoyDPad::getParentSet() { return m_parentSet; } void JoyDPad::establishPropertyUpdatedConnection() { connect(this, &JoyDPad::propertyUpdated, getParentSet()->getInputDevice(), &InputDevice::profileEdited); } void JoyDPad::disconnectPropertyUpdatedConnection() { disconnect(this, &JoyDPad::propertyUpdated, getParentSet()->getInputDevice(), &InputDevice::profileEdited); } bool JoyDPad::hasSlotsAssigned() { bool hasSlots = false; QHash temphash = getApplicableButtons(); QHashIterator iter(temphash); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); if (button != nullptr) { if (button->getAssignedSlots()->count() > 0) { hasSlots = true; iter.toBack(); } } } return hasSlots; } void JoyDPad::setButtonsSpringRelativeStatus(bool value) { QHashIterator iter(buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setSpringRelativeStatus(value); } } bool JoyDPad::isRelativeSpring() { bool relative = false; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return relative; JoyDPadButton *button = iter.value(); relative = button->isRelativeSpring(); while (++iter != temphash.cend()) { button = iter.value(); bool temp = button->isRelativeSpring(); if (temp != relative) { relative = false; break; } } return relative; } void JoyDPad::copyAssignments(JoyDPad *destDPad) { destDPad->activeDiagonalButton = activeDiagonalButton; destDPad->prevDirection = prevDirection; destDPad->currentMode = currentMode; destDPad->dpadDelay = dpadDelay; QHashIterator iter(destDPad->buttons); while (iter.hasNext()) { JoyDPadButton *destButton = iter.next().value(); if (destButton != nullptr) { JoyDPadButton *sourceButton = buttons.value(destButton->getDirection()); if (sourceButton != nullptr) { sourceButton->copyAssignments(destButton); } } } if (!destDPad->isDefault()) { emit propertyUpdated(); } } void JoyDPad::createDeskEvent(bool ignoresets) { JoyDPadButton *curButton = nullptr; JoyDPadButton *prevButton = nullptr; JoyDPadButton::JoyDPadDirections value = pendingDirection; if (pendingDirection != prevDirection) { if (activeDiagonalButton != nullptr) { activeDiagonalButton->joyEvent(false, ignoresets); activeDiagonalButton = nullptr; } else { if (currentMode == StandardMode) { if ((prevDirection & JoyDPadButton::DpadUp) && (!(value & JoyDPadButton::DpadUp))) { prevButton = buttons.value(JoyDPadButton::DpadUp); prevButton->joyEvent(false, ignoresets); } if ((prevDirection & JoyDPadButton::DpadDown) && (!(value & JoyDPadButton::DpadDown))) { prevButton = buttons.value(JoyDPadButton::DpadDown); prevButton->joyEvent(false, ignoresets); } if ((prevDirection & JoyDPadButton::DpadLeft) && (!(value & JoyDPadButton::DpadLeft))) { prevButton = buttons.value(JoyDPadButton::DpadLeft); prevButton->joyEvent(false, ignoresets); } if ((prevDirection & JoyDPadButton::DpadRight) && (!(value & JoyDPadButton::DpadRight))) { prevButton = buttons.value(JoyDPadButton::DpadRight); prevButton->joyEvent(false, ignoresets); } } else if ((currentMode == EightWayMode) && prevDirection) { prevButton = buttons.value(prevDirection); prevButton->joyEvent(false, ignoresets); } else if ((currentMode == FourWayCardinal) && (static_cast(prevDirection) != 0)) { if (((prevDirection == JoyDPadButton::DpadUp) || (prevDirection == JoyDPadButton::DpadRightUp)) && ((value != JoyDPadButton::DpadUp) && (value != JoyDPadButton::DpadRightUp))) { prevButton = buttons.value(JoyDPadButton::DpadUp); } else if (((prevDirection == JoyDPadButton::DpadDown) || (prevDirection == JoyDPadButton::DpadLeftDown)) && ((value != JoyDPadButton::DpadDown) && (value != JoyDPadButton::DpadLeftDown))) { prevButton = buttons.value(JoyDPadButton::DpadDown); } else if (((prevDirection == JoyDPadButton::DpadLeft) || (prevDirection == JoyDPadButton::DpadLeftUp)) && ((value != JoyDPadButton::DpadLeft) && (value != JoyDPadButton::DpadLeftUp))) { prevButton = buttons.value(JoyDPadButton::DpadLeft); } else if (((prevDirection == JoyDPadButton::DpadRight) || (prevDirection == JoyDPadButton::DpadRightDown)) && ((value != JoyDPadButton::DpadRight) && (value != JoyDPadButton::DpadRightDown))) { prevButton = buttons.value(JoyDPadButton::DpadRight); } if (prevButton != nullptr) { prevButton->joyEvent(false, ignoresets); } } else if ((currentMode == FourWayDiagonal) && (static_cast(prevDirection) != 0)) { prevButton = buttons.value(prevDirection); prevButton->joyEvent(false, ignoresets); } } switch (currentMode) { case StandardMode: { if ((value & JoyDPadButton::DpadUp) && (!(prevDirection & JoyDPadButton::DpadUp))) { curButton = buttons.value(JoyDPadButton::DpadUp); curButton->joyEvent(true, ignoresets); } if ((value & JoyDPadButton::DpadDown) && (!(prevDirection & JoyDPadButton::DpadDown))) { curButton = buttons.value(JoyDPadButton::DpadDown); curButton->joyEvent(true, ignoresets); } if ((value & JoyDPadButton::DpadLeft) && (!(prevDirection & JoyDPadButton::DpadLeft))) { curButton = buttons.value(JoyDPadButton::DpadLeft); curButton->joyEvent(true, ignoresets); } if ((value & JoyDPadButton::DpadRight) && (!(prevDirection & JoyDPadButton::DpadRight))) { curButton = buttons.value(JoyDPadButton::DpadRight); curButton->joyEvent(true, ignoresets); } break; } case EightWayMode: { switch (value) { case JoyDPadButton::DpadLeftUp: { activeDiagonalButton = buttons.value(JoyDPadButton::DpadLeftUp); activeDiagonalButton->joyEvent(true, ignoresets); break; } case JoyDPadButton::DpadRightUp: { activeDiagonalButton = buttons.value(JoyDPadButton::DpadRightUp); activeDiagonalButton->joyEvent(true, ignoresets); break; } case JoyDPadButton::DpadRightDown: { activeDiagonalButton = buttons.value(JoyDPadButton::DpadRightDown); activeDiagonalButton->joyEvent(true, ignoresets); break; } case JoyDPadButton::DpadLeftDown: { activeDiagonalButton = buttons.value(JoyDPadButton::DpadLeftDown); activeDiagonalButton->joyEvent(true, ignoresets); break; } case JoyDPadButton::DpadUp: { curButton = buttons.value(JoyDPadButton::DpadUp); curButton->joyEvent(true, ignoresets); break; } case JoyDPadButton::DpadDown: { curButton = buttons.value(JoyDPadButton::DpadDown); curButton->joyEvent(true, ignoresets); break; } case JoyDPadButton::DpadLeft: { curButton = buttons.value(JoyDPadButton::DpadLeft); curButton->joyEvent(true, ignoresets); break; } case JoyDPadButton::DpadRight: { curButton = buttons.value(JoyDPadButton::DpadRight); curButton->joyEvent(true, ignoresets); break; } default: break; } break; } case FourWayCardinal: { if ((value == JoyDPadButton::DpadUp) || (value == JoyDPadButton::DpadRightUp)) { curButton = buttons.value(JoyDPadButton::DpadUp); curButton->joyEvent(true, ignoresets); } else if ((value == JoyDPadButton::DpadDown) || (value == JoyDPadButton::DpadLeftDown)) { curButton = buttons.value(JoyDPadButton::DpadDown); curButton->joyEvent(true, ignoresets); } else if ((value == JoyDPadButton::DpadLeft) || (value == JoyDPadButton::DpadLeftUp)) { curButton = buttons.value(JoyDPadButton::DpadLeft); curButton->joyEvent(true, ignoresets); } else if ((value == JoyDPadButton::DpadRight) || (value == JoyDPadButton::DpadRightDown)) { curButton = buttons.value(JoyDPadButton::DpadRight); curButton->joyEvent(true, ignoresets); } break; } case FourWayDiagonal: { switch (value) { case JoyDPadButton::DpadLeftUp: { activeDiagonalButton = buttons.value(JoyDPadButton::DpadLeftUp); activeDiagonalButton->joyEvent(true, ignoresets); break; } case JoyDPadButton::DpadRightUp: { activeDiagonalButton = buttons.value(JoyDPadButton::DpadRightUp); activeDiagonalButton->joyEvent(true, ignoresets); break; } case JoyDPadButton::DpadRightDown: { activeDiagonalButton = buttons.value(JoyDPadButton::DpadRightDown); activeDiagonalButton->joyEvent(true, ignoresets); break; } case JoyDPadButton::DpadLeftDown: { activeDiagonalButton = buttons.value(JoyDPadButton::DpadLeftDown); activeDiagonalButton->joyEvent(true, ignoresets); break; } default: break; } break; } } prevDirection = pendingDirection; } } void JoyDPad::dpadDirectionChangeEvent() { createDeskEvent(); } void JoyDPad::setDPadDelay(int value) { if (((value >= 10) && (value <= 1000)) || (value == 0)) { this->dpadDelay = value; emit dpadDelayChanged(value); emit propertyUpdated(); } } int JoyDPad::getDPadDelay() { return dpadDelay; } void JoyDPad::setButtonsEasingDuration(double value) { QHash temphash = getApplicableButtons(); QHashIterator iter(temphash); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setEasingDuration(value); } } double JoyDPad::getButtonsEasingDuration() { double result = GlobalVariables::JoyButton::DEFAULTEASINGDURATION; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyDPadButton *button = iter.value(); result = button->getEasingDuration(); while (++iter != temphash.cend()) { button = iter.value(); double temp = button->getEasingDuration(); if (!qFuzzyCompare(temp, result)) { result = GlobalVariables::JoyButton::DEFAULTEASINGDURATION; break; } } return result; } void JoyDPad::setButtonsSpringDeadCircleMultiplier(int value) { QHash temphash = getApplicableButtons(); QHashIterator iter(temphash); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setSpringDeadCircleMultiplier(value); } } int JoyDPad::getButtonsSpringDeadCircleMultiplier() { int result = GlobalVariables::JoyButton::DEFAULTSPRINGRELEASERADIUS; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyDPadButton *button = iter.value(); result = button->getSpringDeadCircleMultiplier(); while (++iter != temphash.cend()) { button = iter.value(); int temp = button->getSpringDeadCircleMultiplier(); if (temp != result) { result = GlobalVariables::JoyButton::DEFAULTSPRINGRELEASERADIUS; break; } } return result; } void JoyDPad::setButtonsExtraAccelerationCurve(JoyButton::JoyExtraAccelerationCurve curve) { QHash temphash = getApplicableButtons(); QHashIterator iter(temphash); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setExtraAccelerationCurve(curve); } } JoyButton::JoyExtraAccelerationCurve JoyDPad::getButtonsExtraAccelerationCurve() { JoyButton::JoyExtraAccelerationCurve result = JoyButton::LinearAccelCurve; QHash temphash = getApplicableButtons(); auto iter = temphash.cbegin(); if (iter == temphash.cend()) return result; JoyDPadButton *button = iter.value(); result = button->getExtraAccelerationCurve(); while (++iter != temphash.cend()) { button = iter.value(); JoyButton::JoyExtraAccelerationCurve temp = button->getExtraAccelerationCurve(); if (temp != result) { result = JoyButton::LinearAccelCurve; break; } } return result; } QHash JoyDPad::getDirectionButtons(JoyDPadButton::JoyDPadDirections direction) { QHash temphash; switch (currentMode) { case StandardMode: { if (direction & JoyDPadButton::DpadUp) { temphash.insert(JoyDPadButton::DpadUp, buttons.value(JoyDPadButton::DpadUp)); } if (direction & JoyDPadButton::DpadDown) { temphash.insert(JoyDPadButton::DpadDown, buttons.value(JoyDPadButton::DpadDown)); } if (direction & JoyDPadButton::DpadLeft) { temphash.insert(JoyDPadButton::DpadLeft, buttons.value(JoyDPadButton::DpadLeft)); } if (direction & JoyDPadButton::DpadRight) { temphash.insert(JoyDPadButton::DpadRight, buttons.value(JoyDPadButton::DpadRight)); } break; } case EightWayMode: { if (direction != JoyDPadButton::DpadCentered) { temphash.insert(direction, buttons.value(direction)); } break; } case FourWayCardinal: { if ((direction == JoyDPadButton::DpadUp) || (direction == JoyDPadButton::DpadDown) || (direction == JoyDPadButton::DpadLeft) || (direction == JoyDPadButton::DpadRight)) { temphash.insert(direction, buttons.value(direction)); } break; } case FourWayDiagonal: { if ((direction == JoyDPadButton::DpadRightUp) || (direction == JoyDPadButton::DpadRightDown) || (direction == JoyDPadButton::DpadLeftDown) || (direction == JoyDPadButton::DpadLeftUp)) { temphash.insert(direction, buttons.value(direction)); } break; } } return temphash; } void JoyDPad::setDirButtonsUpdateInitAccel(JoyDPadButton::JoyDPadDirections direction, bool state) { QHash apphash = getDirectionButtons(direction); QHashIterator iter(apphash); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); if (button != nullptr) { button->setUpdateInitAccel(state); } } } void JoyDPad::copyLastDistanceValues(JoyDPad *srcDPad) { QHash apphash = srcDPad->getApplicableButtons(); QHashIterator iter(apphash); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); if ((button != nullptr) && button->getButtonState()) { this->buttons.value(iter.key())->copyLastAccelerationDistance(button); this->buttons.value(iter.key())->copyLastMouseDistanceFromDeadZone(button); } } } void JoyDPad::eventReset() { QHash temphash = getApplicableButtons(); QHashIterator iter(temphash); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->eventReset(); } } AntiMicroX-antimicrox-b300273/src/joydpad.h000066400000000000000000000116031471077622000205450ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYDPAD_H #define JOYDPAD_H #include "joybuttontypes/joydpadbutton.h" class JoyDPad : public QObject { Q_OBJECT public: explicit JoyDPad(int index, int originset, SetJoystick *parentSet, QObject *parent); enum JoyMode { StandardMode = 0, EightWayMode, FourWayCardinal, FourWayDiagonal }; JoyDPadButton *getJoyButton(int index_local); QHash *getJoyButtons(); int getCurrentDirection(); int getJoyNumber(); int getIndex(); int getRealJoyNumber(); virtual QString getName(bool fullForceFormat = false, bool displayNames = false); void joyEvent(int value, bool ignoresets = false); // JoyDPadEvent class void queuePendingEvent(int value, bool ignoresets = false); // JoyDPadEvent class void activatePendingEvent(); // JoyDPadEvent class bool hasPendingEvent(); // JoyDPadEvent class void clearPendingEvent(); // JoyDPadEvent class void setJoyMode(JoyMode mode); JoyMode getJoyMode(); void releaseButtonEvents(); // JoyDPadEvent class void setButtonsMouseMode(JoyButton::JoyMouseMovementMode mode); bool hasSameButtonsMouseMode(); JoyButton::JoyMouseMovementMode getButtonsPresetMouseMode(); void setButtonsMouseCurve(JoyButton::JoyMouseCurve mouseCurve); bool hasSameButtonsMouseCurve(); JoyButton::JoyMouseCurve getButtonsPresetMouseCurve(); void setButtonsSpringWidth(int value); int getButtonsPresetSpringWidth(); void setButtonsSpringHeight(int value); int getButtonsPresetSpringHeight(); void setButtonsSensitivity(double value); double getButtonsPresetSensitivity(); void setButtonsWheelSpeedX(int value); void setButtonsWheelSpeedY(int value); const QString getDpadName(); const QString getDefaultDpadName(); virtual bool isDefault(); QHash *getButtons(); virtual QString getXmlName(); // JoyDPadXml class virtual void setDefaultDPadName(QString tempname); virtual QString getDefaultDPadName(); SetJoystick *getParentSet(); bool hasSlotsAssigned(); bool isRelativeSpring(); void copyAssignments(JoyDPad *destDPad); int getDPadDelay(); double getButtonsEasingDuration(); void setButtonsSpringDeadCircleMultiplier(int value); int getButtonsSpringDeadCircleMultiplier(); void setButtonsExtraAccelerationCurve(JoyButton::JoyExtraAccelerationCurve curve); JoyButton::JoyExtraAccelerationCurve getButtonsExtraAccelerationCurve(); QHash getDirectionButtons(JoyDPadButton::JoyDPadDirections direction); void setDirButtonsUpdateInitAccel(JoyDPadButton::JoyDPadDirections direction, bool state); void copyLastDistanceValues(JoyDPad *srcDPad); virtual void eventReset(); // JoyDPadEvent class signals: void active(int value); void released(int value); void dpadNameChanged(); void dpadDelayChanged(int value); void joyModeChanged(); void propertyUpdated(); public slots: void setDPadName(QString tempName); void setButtonsSpringRelativeStatus(bool value); void setDPadDelay(int value); void setButtonsEasingDuration(double value); void establishPropertyUpdatedConnection(); void disconnectPropertyUpdatedConnection(); private slots: void dpadDirectionChangeEvent(); protected: void populateButtons(); void createDeskEvent(bool ignoresets = false); // JoyDPadEvent class QHash getApplicableButtons(); private: QHash buttons; JoyDPadButton::JoyDPadDirections prevDirection; JoyDPadButton::JoyDPadDirections pendingDirection; JoyDPadButton *activeDiagonalButton; QString dpadName; QString defaultDPadName; SetJoystick *m_parentSet; QTimer directionDelayTimer; JoyMode currentMode; int m_index; int m_originset; int dpadDelay; // unsigned int pendingEventDirection; bool pendingEvent; bool pendingIgnoreSets; }; #endif // JOYDPAD_H AntiMicroX-antimicrox-b300273/src/joygyroscopesensor.cpp000066400000000000000000000177561471077622000234530ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define _USE_MATH_DEFINES #include "joygyroscopesensor.h" #include "globalvariables.h" #include "joybuttontypes/joygyroscopebutton.h" #include JoyGyroscopeSensor::JoyGyroscopeSensor(int originset, SetJoystick *parent_set, QObject *parent) : JoySensor(GYROSCOPE, originset, parent_set, parent) { reset(); populateButtons(); } JoyGyroscopeSensor::~JoyGyroscopeSensor() {} /** * @brief Get the value for the corresponding X axis. * @return X axis value in °/s */ float JoyGyroscopeSensor::getXCoordinate() const { return radToDeg(m_current_value[0]); } /** * @brief Get the value for the corresponding Y axis. * @return Y axis value in °/s */ float JoyGyroscopeSensor::getYCoordinate() const { return radToDeg(m_current_value[1]); } /** * @brief Get the value for the corresponding Z axis. * @return Z axis value in °/s */ float JoyGyroscopeSensor::getZCoordinate() const { return radToDeg(m_current_value[2]); } /** * @brief Get the translated sensor type name * @returns Translated sensor type name */ QString JoyGyroscopeSensor::sensorTypeName() const { return tr("Gyroscope"); } /** * @brief Reads the calibration values of the sensor * @param[out] offsetX Offset value for X axis * @param[out] offsetY Offset value for Y axis * @param[out] offsetZ Offset value for Z axis */ void JoyGyroscopeSensor::getCalibration(double *offsetX, double *offsetY, double *offsetZ) const { *offsetX = m_calibration_value[0]; *offsetY = m_calibration_value[1]; *offsetZ = m_calibration_value[2]; } /** * @brief Sets the sensor calibration values and sets the calibration flag. * @param[in] offsetX Offset value for X axis * @param[in] offsetY Offset value for Y axis * @param[in] offsetZ Offset value for Z axis */ void JoyGyroscopeSensor::setCalibration(double offsetX, double offsetY, double offsetZ) { m_calibration_value[0] = offsetX; m_calibration_value[1] = offsetY; m_calibration_value[2] = offsetZ; m_calibrated = true; } /** * @brief Resets internal variables back to default */ void JoyGyroscopeSensor::reset() { JoySensor::reset(); m_max_zone = degToRad(GlobalVariables::JoySensor::GYRO_MAX); } /** * @brief Initializes the JoySensorButton objects for this sensor. */ void JoyGyroscopeSensor::populateButtons() { JoySensorButton *button = nullptr; button = new JoyGyroscopeButton(this, SENSOR_LEFT, m_originset, getParentSet(), this); m_buttons.insert(SENSOR_LEFT, button); button = new JoyGyroscopeButton(this, SENSOR_RIGHT, m_originset, getParentSet(), this); m_buttons.insert(SENSOR_RIGHT, button); button = new JoyGyroscopeButton(this, SENSOR_UP, m_originset, getParentSet(), this); m_buttons.insert(SENSOR_UP, button); button = new JoyGyroscopeButton(this, SENSOR_DOWN, m_originset, getParentSet(), this); m_buttons.insert(SENSOR_DOWN, button); button = new JoyGyroscopeButton(this, SENSOR_FWD, m_originset, getParentSet(), this); m_buttons.insert(SENSOR_FWD, button); button = new JoyGyroscopeButton(this, SENSOR_BWD, m_originset, getParentSet(), this); m_buttons.insert(SENSOR_BWD, button); } /** * @brief Applies calibration to queued input values */ void JoyGyroscopeSensor::applyCalibration() { m_pending_value[0] -= m_calibration_value[0]; m_pending_value[1] -= m_calibration_value[1]; m_pending_value[2] -= m_calibration_value[2]; } /** * @brief Find the direction zone of the current sensor position. * * First, the sensor axis values are normalized so they are on the unit sphere. * Then, the unit sphere is divided into direction zones with the following algorithm: * - Mark a spherical layer around the X axis at +/- the diagonal zone angle * divided by two (called "range" in the code) * Then generate two more spherical layers by rotating the * first layer around the Y and Z axes. * Check if a point is within each layer by comparing the absolute value * of each coordinate against the "range". * If a point is in only one layer, it is in the diagonal zone between two axes. * If a point is in two layers, it is in the orthogonal zone of one axis. * If a point is in three or zero zones, it is diagonal to all three axes. * There are two cases here because the spherical layers overlap if the diagonal * angle is larger then 45 degree. * * @returns JoySensorDirection bitfield for the current direction zone. */ JoySensorDirection JoyGyroscopeSensor::calculateSensorDirection() { double distance = calculateDistance(); if (distance < m_dead_zone) return SENSOR_CENTERED; double range = sin(M_PI / 4 - m_diagonal_range / 2); double normPitch = m_current_value[0] / distance; double normRoll = m_current_value[1] / distance; double normYaw = m_current_value[2] / distance; bool inPitch = abs(normPitch) < range; bool inRoll = abs(normRoll) < range; bool inYaw = abs(normYaw) < range; if (inPitch && !inRoll && !inYaw) { if (normRoll > 0) { if (normYaw > 0) return SENSOR_RIGHT_FWD; else return SENSOR_LEFT_FWD; } else { if (normYaw > 0) return SENSOR_RIGHT_BWD; else return SENSOR_LEFT_BWD; } } else if (!inPitch && inRoll && !inYaw) { if (normPitch > 0) { if (normYaw > 0) return SENSOR_RIGHT_UP; else return SENSOR_LEFT_UP; } else { if (normYaw > 0) return SENSOR_RIGHT_DOWN; else return SENSOR_LEFT_DOWN; } } else if (!inPitch && !inRoll && inYaw) { if (normPitch > 0) { if (normRoll > 0) return SENSOR_UP_FWD; else return SENSOR_UP_BWD; } else { if (normRoll > 0) return SENSOR_DOWN_FWD; else return SENSOR_DOWN_BWD; } } else if (inPitch && inRoll && !inYaw) { if (normYaw > 0) return SENSOR_RIGHT; else return SENSOR_LEFT; } else if (inPitch && !inRoll && inYaw) { if (normRoll > 0) return SENSOR_FWD; else return SENSOR_BWD; } else if (!inPitch && inRoll && inYaw) { if (normPitch > 0) return SENSOR_UP; else return SENSOR_DOWN; } else // in all or in none { if (normPitch > 0) { if (normRoll > 0) { if (normYaw > 0) return SENSOR_RIGHT_UP_FWD; else return SENSOR_LEFT_UP_FWD; } else { if (normYaw > 0) return SENSOR_RIGHT_UP_BWD; else return SENSOR_LEFT_UP_BWD; } } else { if (normRoll > 0) { if (normYaw > 0) return SENSOR_RIGHT_DOWN_FWD; else return SENSOR_LEFT_DOWN_FWD; } else { if (normYaw > 0) return SENSOR_RIGHT_DOWN_BWD; else return SENSOR_LEFT_DOWN_BWD; } } } } AntiMicroX-antimicrox-b300273/src/joygyroscopesensor.h000066400000000000000000000031651471077622000231050ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "joysensor.h" class SetJoystick; /** * @brief Represents a gyroscope sensor. */ class JoyGyroscopeSensor : public JoySensor { public: explicit JoyGyroscopeSensor(int originset, SetJoystick *parent_set, QObject *parent); virtual ~JoyGyroscopeSensor(); virtual float getXCoordinate() const override; virtual float getYCoordinate() const override; virtual float getZCoordinate() const override; virtual QString sensorTypeName() const override; virtual void getCalibration(double *offsetX, double *offsetY, double *offsetZ) const override; virtual void setCalibration(double offsetX, double offsetY, double offsetZ) override; public slots: virtual void reset() override; protected: virtual void populateButtons(); virtual JoySensorDirection calculateSensorDirection() override; virtual void applyCalibration() override; }; AntiMicroX-antimicrox-b300273/src/joykeyrepeathelper.cpp000066400000000000000000000040011471077622000233530ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joykeyrepeathelper.h" #include "event.h" #include "joybuttonslot.h" JoyKeyRepeatHelper::JoyKeyRepeatHelper(QObject *parent) : QObject(parent) { lastActiveKey = 0; keyRepeatTimer.setParent(this); connect(&keyRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKeysEvent())); } QTimer *JoyKeyRepeatHelper::getRepeatTimer() { return &keyRepeatTimer; } void JoyKeyRepeatHelper::repeatKeysEvent() { if (lastActiveKey) { JoyButtonSlot *slot = lastActiveKey; // Send another key press to fake a key repeat sendevent(slot); keyRepeatTimer.start(keyRepeatRate); } else { keyRepeatTimer.stop(); } } void JoyKeyRepeatHelper::setLastActiveKey(JoyButtonSlot *slot) { lastActiveKey = slot; } JoyButtonSlot *JoyKeyRepeatHelper::getLastActiveKey() { return lastActiveKey; } /*void JoyKeyRepeatHelper::setKeyRepeatDelay(unsigned int repeatDelay) { if (repeatDelay > 0) { keyRepeatDelay = repeatDelay; } } unsigned int JoyKeyRepeatHelper::getKeyRepeatDelay() { return keyRepeatDelay; } */ void JoyKeyRepeatHelper::setKeyRepeatRate(int repeatRate) { if (repeatRate > 0) { keyRepeatRate = repeatRate; } } int JoyKeyRepeatHelper::getKeyRepeatRate() { return keyRepeatRate; } AntiMicroX-antimicrox-b300273/src/joykeyrepeathelper.h000066400000000000000000000026641471077622000230350ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYKEYREPEATHELPER_H #define JOYKEYREPEATHELPER_H #include #include class JoyButtonSlot; class JoyKeyRepeatHelper : public QObject { Q_OBJECT public: explicit JoyKeyRepeatHelper(QObject *parent = nullptr); QTimer *getRepeatTimer(); void setLastActiveKey(JoyButtonSlot *slot); JoyButtonSlot *getLastActiveKey(); void setKeyRepeatRate(int repeatRate); int getKeyRepeatRate(); private slots: void repeatKeysEvent(); protected: QTimer keyRepeatTimer; JoyButtonSlot *lastActiveKey; int keyRepeatDelay; int keyRepeatRate; }; #endif // JOYKEYREPEATHELPER_H AntiMicroX-antimicrox-b300273/src/joysensor.cpp000066400000000000000000000647401471077622000215130ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define _USE_MATH_DEFINES #include "joysensor.h" #include "inputdevice.h" #include "joybuttontypes/joysensorbutton.h" #include "xml/joybuttonxml.h" #include #include #include JoySensor::JoySensor(JoySensorType type, int originset, SetJoystick *parent_set, QObject *parent) : QObject(parent) , m_type(type) , m_calibrated(false) , m_pending_event(false) , m_originset(originset) , m_parent_set(parent_set) { reset(); m_delay_timer.setSingleShot(true); connect(&m_delay_timer, &QTimer::timeout, this, &JoySensor::delayTimerExpired); } JoySensor::~JoySensor() {} /** * @brief Main sensor mapping function. * When activated, it generates a "moved" QT event which updates various parts of the UI. * Furthermore, it controls the sensor delay timer and calculates the current sensor * direction and generates "active" and "released" QT events which enable/disable * button highlights in the GUI. * Finally, it calls createDeskEvent if the active/released button state has changed. */ void JoySensor::joyEvent(float *values, bool ignoresets) { m_current_value[0] = values[0]; m_current_value[1] = values[1]; m_current_value[2] = values[2]; JoySensorDirection pending_direction = calculateSensorDirection(); if (pending_direction != SENSOR_CENTERED && !m_active) { m_active = true; emit active(m_current_value[0], m_current_value[1], m_current_value[2]); if (ignoresets || (m_sensor_delay == 0)) { if (m_delay_timer.isActive()) m_delay_timer.stop(); createDeskEvent(pending_direction, ignoresets); } else { if (!m_delay_timer.isActive()) m_delay_timer.start(m_sensor_delay); } } else if (pending_direction == SENSOR_CENTERED && m_active) { m_active = false; emit released(m_current_value[0], m_current_value[1], m_current_value[2]); if (ignoresets || (m_sensor_delay == 0)) { if (m_delay_timer.isActive()) m_delay_timer.stop(); createDeskEvent(pending_direction, ignoresets); } else { if (!m_delay_timer.isActive()) m_delay_timer.start(m_sensor_delay); } } else if (m_active) { if (ignoresets || (m_sensor_delay == 0)) { if (m_delay_timer.isActive()) m_delay_timer.stop(); createDeskEvent(pending_direction, ignoresets); } else { if (m_current_direction != pending_direction) { if (!m_delay_timer.isActive()) m_delay_timer.start(m_sensor_delay); } else { if (m_delay_timer.isActive()) m_delay_timer.stop(); createDeskEvent(pending_direction, ignoresets); } } } emit moved(m_current_value[0], m_current_value[1], m_current_value[2]); } /** * @brief Queues next movement event from InputDaemon */ void JoySensor::queuePendingEvent(float *values, bool ignoresets) { m_pending_value[0] = values[0]; m_pending_value[1] = values[1]; m_pending_value[2] = values[2]; if (m_calibrated) applyCalibration(); m_pending_event = true; m_pending_ignore_sets = ignoresets; } /** * @brief Activates previously queued movement event * This is called by InputDevice. */ void JoySensor::activatePendingEvent() { if (!m_pending_event) return; joyEvent(m_pending_value, m_pending_ignore_sets); clearPendingEvent(); } /** * @brief Checks if an event is queued * @returns True if an event is queued, false otherwise. */ bool JoySensor::hasPendingEvent() const { return m_pending_event; } /** * @brief Clears a previously queued event */ void JoySensor::clearPendingEvent() { m_pending_event = false; m_pending_ignore_sets = false; } /** * @brief Copy slots from all sensor buttons and properties from a sensor * onto another. * @param JoySensor object to be modified. */ void JoySensor::copyAssignments(JoySensor *dest_sensor) { dest_sensor->reset(); dest_sensor->m_dead_zone = m_dead_zone; dest_sensor->m_max_zone = m_max_zone; dest_sensor->m_diagonal_range = m_diagonal_range; dest_sensor->m_sensor_name = m_sensor_name; dest_sensor->m_sensor_delay = m_sensor_delay; dest_sensor->m_calibrated = m_calibrated; dest_sensor->m_calibration_value[0] = m_calibration_value[0]; dest_sensor->m_calibration_value[1] = m_calibration_value[1]; dest_sensor->m_calibration_value[2] = m_calibration_value[2]; auto dest_buttons = dest_sensor->getButtons(); for (auto iter = dest_buttons->begin(); iter != dest_buttons->end(); ++iter) { JoySensorButton *dest_button = iter.value(); if (dest_button != nullptr) { JoySensorButton *source_button = m_buttons.value(dest_button->getDirection()); if (source_button != nullptr) source_button->copyAssignments(dest_button); } } if (!dest_sensor->isDefault()) emit propertyUpdated(); } /** * @brief Check if any direction is mapped to a keyboard or mouse event * @returns True if a mapping exists, false otherwise */ bool JoySensor::hasSlotsAssigned() const { for (const auto &button : m_buttons) { if (button != nullptr) { if (button->getAssignedSlots()->count() > 0) return true; } } return false; } /** * @brief Get the name of this sensor * @returns Sensor name */ QString JoySensor::getPartialName(bool forceFullFormat, bool displayNames) const { QString label = QString(); if (!m_sensor_name.isEmpty() && displayNames) { if (forceFullFormat) { label.append(sensorTypeName()).append(" "); } label.append(m_sensor_name); } else { label.append(sensorTypeName()).append(" "); } return label; } /** * @brief Returns the sensor name */ QString JoySensor::getSensorName() const { return m_sensor_name; } /** * @brief Returns the sensor type */ JoySensorType JoySensor::getType() const { return m_type; } /** * @brief Returns the current sensor direction */ JoySensorDirection JoySensor::getCurrentDirection() const { return m_current_direction; } /** * @brief Get the assigned dead zone value * @return Assigned dead zone value in degree or degree/s */ double JoySensor::getDeadZone() const { return radToDeg(m_dead_zone); } /** * @brief Get the assigned diagonal range value * @return Assigned diagonal range in degree or degree/s */ double JoySensor::getDiagonalRange() const { return radToDeg(m_diagonal_range); } /** * @brief Get the assigned max zone value * @return Assigned max zone value in degree or degree/s */ double JoySensor::getMaxZone() const { return radToDeg(m_max_zone); } /** * @brief Get the assigned input delay * @returns Input delay in ms */ unsigned int JoySensor::getSensorDelay() const { return m_sensor_delay; } /** * @brief Checks if the sensor vector is currently in the dead zone * @returns True if it is in the dead zone, false otherwise */ bool JoySensor::inDeadZone(float *values) const { return calculateDistance(values[0], values[1], values[2]) < m_dead_zone; } /** * @brief Get current radial distance of the sensor past the assigned * dead zone. * @return Distance between 0 and max zone in radiants. */ double JoySensor::getDistanceFromDeadZone() const { return getDistanceFromDeadZone(m_current_value[0], m_current_value[1], m_current_value[2]); } /** * @brief Get radial distance of the sensor past the assigned dead zone * based on the passed X, Y and Z axes values associated with the sensor. * @param X axis value * @param Y axis value * @param Z axis value * @return Distance between 0 and max zone in radiants. */ double JoySensor::getDistanceFromDeadZone(double x, double y, double z) const { double distance = calculateDistance(x, y, z); return qBound(0.0, distance - m_dead_zone, m_max_zone); } /** * @brief Get current X distance of the sensor past the assigned * dead zone. * @return Distance between 0 and max zone in radiants. */ double JoySensor::calculateXDistanceFromDeadZone() const { return calculateXDistanceFromDeadZone(m_current_value[0], m_current_value[1], m_current_value[2]); } /** * @brief Get current X distance of the sensor past the assigned * dead zone based on the passed X, Y and Z axes values associated * with the sensor. The algorithm checks if an axis parallel line * through the current sensor position intersects with the dead zone * sphere and subtracts the line segment within the sphere from the * distance. The resulting value is not normalized because there is no * practical maximum value for a sensor as you can always move it a bit faster. * @param X axis value * @param Y axis value * @param Z axis value * @return Distance between 0 and max zone in radiants. */ double JoySensor::calculateXDistanceFromDeadZone(double x, double y, double z) const { double discriminant = m_dead_zone * m_dead_zone - y * y - z * z; if (discriminant <= 0) return std::min(abs(x), m_max_zone); else return std::min(abs(x) - sqrt(discriminant), m_max_zone); } /** * @brief Get current Y distance of the sensor past the assigned * dead zone. * @return Distance between 0 and max zone in radiants. */ double JoySensor::calculateYDistanceFromDeadZone() const { return calculateYDistanceFromDeadZone(m_current_value[0], m_current_value[1], m_current_value[2]); } /** * @brief Get current Y distance of the sensor past the assigned * dead zone based on the passed X, Y and Z axes values associated * with the sensor. The algorithm checks if an axis parallel line * through the current sensor position intersects with the dead zone * sphere and subtracts the line segment within the sphere from the * distance. The resulting value is not normalized because there is no * practical maximum value for a sensor as you can always move it a bit faster. * @param X axis value * @param Y axis value * @param Z axis value * @return Distance between 0 and max zone in radiants. */ double JoySensor::calculateYDistanceFromDeadZone(double x, double y, double z) const { double discriminant = m_dead_zone * m_dead_zone - x * x - z * z; if (discriminant <= 0) return std::min(abs(y), m_max_zone); else return std::min(abs(y) - sqrt(discriminant), m_max_zone); } /** * @brief Get current Z distance of the sensor past the assigned * dead zone. * @return Distance between 0 and max zone in radiants. */ double JoySensor::calculateZDistanceFromDeadZone() const { return calculateZDistanceFromDeadZone(m_current_value[0], m_current_value[1], m_current_value[2]); } /** * @brief Get current Z distance of the sensor past the assigned * dead zone based on the passed X, Y and Z axes values associated * with the sensor. The algorithm checks if an axis parallel line * through the current sensor position intersects with the dead zone * sphere and subtracts the line segment within the sphere from the * distance. The resulting value is not normalized because there is no * practical maximum value for a sensor as you can always move it a bit faster. * @param X axis value * @param Y axis value * @param Z axis value * @return Distance between 0 and max zone in radiants. */ double JoySensor::calculateZDistanceFromDeadZone(double x, double y, double z) const { double discriminant = m_dead_zone * m_dead_zone - x * x - y * y; if (discriminant <= 0) return std::min(abs(z), m_max_zone); else return std::min(abs(z) - sqrt(discriminant), m_max_zone); } /** * @brief Get the vector length of the sensor * @return Vector length */ double JoySensor::calculateDistance() const { return calculateDistance(m_current_value[0], m_current_value[1], m_current_value[2]); } /** * @brief Get the vector length of the sensor based on the passed * X, Y and Z axes values associated with the sensor. * @return Vector length */ double JoySensor::calculateDistance(double x, double y, double z) const { return sqrt(x * x + y * y + z * z); } /** * @brief Calculate the pitch angle (in degrees) corresponding to the current * position of controller. * @return Pitch (in degrees) */ double JoySensor::calculatePitch() const { return calculatePitch(m_current_value[0], m_current_value[1], m_current_value[2]); } /** * @brief Calculate the pitch angle (in degrees) corresponding to the current * passed X, Y and Z axes values associated with the sensor. * position of controller. * See https://www.nxp.com/files-static/sensors/doc/app_note/AN3461.pdf * for a description of the used algorithm. * @param X axis value * @param Y axis value * @param Z axis value * @return Pitch (in degrees) */ double JoySensor::calculatePitch(double x, double y, double z) const { double rad = calculateDistance(x, y, z); double pitch = -atan2(z / rad, y / rad) - M_PI / 2; if (pitch < -M_PI) pitch += 2 * M_PI; return pitch; } /** * @brief Calculate the roll angle (in degrees) corresponding to the current * position of controller. * @return Roll (in degrees) */ double JoySensor::calculateRoll() const { return calculateRoll(m_current_value[0], m_current_value[1], m_current_value[2]); } /** * @brief Calculate the roll angle (in degrees) corresponding to the current * passed X, Y and Z axes values associated with the sensor. * position of controller. * See https://www.nxp.com/files-static/sensors/doc/app_note/AN3461.pdf * for a description of the used algorithm. * @param X axis value * @param Y axis value * @param Z axis value * @return Roll (in degrees) */ double JoySensor::calculateRoll(double x, double y, double z) const { double rad = calculateDistance(x, y, z); double xp, yp, zp; xp = x / rad; yp = y / rad; zp = z / rad; double roll = atan2(sqrt(yp * yp + zp * zp), -xp) - M_PI / 2; if (roll < -M_PI) roll += 2 * M_PI; return roll; } /** * @brief Used to calculate the distance value that should be used by * the JoyButton in the given direction. * @param direction * @return Distance factor that should be used by JoySensorButton */ double JoySensor::calculateDirectionalDistance(JoySensorDirection direction) const { double finalDistance = 0.0; switch (direction) { case JoySensorDirection::SENSOR_LEFT: case JoySensorDirection::SENSOR_RIGHT: // Yaw finalDistance = calculateZDistanceFromDeadZone(); break; case JoySensorDirection::SENSOR_UP: case JoySensorDirection::SENSOR_DOWN: // Pitch finalDistance = calculateXDistanceFromDeadZone(); break; case JoySensorDirection::SENSOR_FWD: case JoySensorDirection::SENSOR_BWD: // Roll finalDistance = calculateYDistanceFromDeadZone(); break; default: break; } return finalDistance; } /** * @brief Utility function which converts a given value from radians to degree. */ double JoySensor::radToDeg(double value) { return value * 180 / M_PI; } /** * @brief Utility function which converts a given value from degree to radians. */ double JoySensor::degToRad(double value) { return value * M_PI / 180; } /** * @brief Check if the sensor is calibrated * @returns True if it is calibrated, false otherwise. */ bool JoySensor::isCalibrated() const { return m_calibrated; } /** * @brief Resets the calibration of the sensor back to uncalibrated state. */ void JoySensor::resetCalibration() { m_calibrated = false; } /** * @brief Returns a QHash which maps the SensorDirection to * the corresponding JoySensorButton. */ QHash *JoySensor::getButtons() { return &m_buttons; } /** * @brief Get a pointer to the sensor direction button for the desired * direction. * @param Value of the direction of the sensor. * @return Pointer to the sensor direction button for the sensor * direction. */ JoySensorButton *JoySensor::getDirectionButton(JoySensorDirection direction) { return m_buttons.value(direction); } /** * @brief Checks if all sensor settings and button mappings are the their default values. * This is used during XML serialization to skip unnecessary objects. * @returns True if everything is at the default, false otherwise. */ bool JoySensor::isDefault() const { bool value = true; value = value && qFuzzyCompare(getDeadZone(), GlobalVariables::JoySensor::DEFAULTDEADZONE); if (m_type == ACCELEROMETER) value = value && qFuzzyCompare(getMaxZone(), GlobalVariables::JoySensor::ACCEL_MAX); else value = value && qFuzzyCompare(getMaxZone(), GlobalVariables::JoySensor::GYRO_MAX); value = value && qFuzzyCompare(getDiagonalRange(), GlobalVariables::JoySensor::DEFAULTDIAGONALRANGE); value = value && (m_sensor_delay == GlobalVariables::JoySensor::DEFAULTSENSORDELAY); for (const auto &button : m_buttons) value = value && (button->isDefault()); return value; } /** * @brief Resets internal variables back to default */ void JoySensor::reset() { m_active = false; for (size_t i = 0; i < ACTIVE_BUTTON_COUNT; ++i) m_active_button[i] = nullptr; m_dead_zone = degToRad(GlobalVariables::JoySensor::DEFAULTDEADZONE); m_diagonal_range = degToRad(GlobalVariables::JoySensor::DEFAULTDIAGONALRANGE); m_pending_event = false; m_current_direction = JoySensorDirection::SENSOR_CENTERED; m_sensor_name.clear(); m_sensor_delay = GlobalVariables::JoySensor::DEFAULTSENSORDELAY; resetButtons(); } /** * @brief Sets the dead zone of the sensor to the given value * @param[in] value New sensor dead zone */ void JoySensor::setDeadZone(double value) { value = abs(degToRad(value)); if (!qFuzzyCompare(value, m_dead_zone) && (value <= m_max_zone)) { m_dead_zone = value; emit deadZoneChanged(value); emit propertyUpdated(); } } /** * @brief Sets the maximum zone of the sensor to the given value * @param[in] value New sensor maximum zone */ void JoySensor::setMaxZone(double value) { value = abs(degToRad(value)); if (!qFuzzyCompare(value, m_max_zone) && (value > m_dead_zone)) { m_max_zone = value; emit maxZoneChanged(value); emit propertyUpdated(); } } /** * @brief Set the diagonal range value for a sensor. * @param Value between 1 - 90. */ void JoySensor::setDiagonalRange(double value) { if (value < 1) value = 1; else if (value > 90) value = 90; value = degToRad(value); if (!qFuzzyCompare(value, m_diagonal_range)) { m_diagonal_range = value; emit diagonalRangeChanged(value); emit propertyUpdated(); } } /** * @brief Sets the sensor input delaqy to the given value * @param[in] value New sensor input delay in ms */ void JoySensor::setSensorDelay(unsigned int value) { if (((value >= 10) && (value <= 1000)) || (value == 0)) { m_sensor_delay = value; emit sensorDelayChanged(value); emit propertyUpdated(); } } /** * @brief Sets the name of this sensor * @param[in] tempName New sensor name */ void JoySensor::setSensorName(QString tempName) { if ((tempName.length() <= 20) && (tempName != m_sensor_name)) { m_sensor_name = tempName; emit sensorNameChanged(); } } void JoySensor::establishPropertyUpdatedConnection() { connect(this, &JoySensor::propertyUpdated, getParentSet()->getInputDevice(), &InputDevice::profileEdited); } /** * @brief Take a XML stream and set the sensor and direction button properties * according to the values contained within the stream. * @param QXmlStreamReader instance that will be used to read property values. */ void JoySensor::readConfig(QXmlStreamReader *xml) { if (xml->isStartElement() && (xml->name().toString() == "sensor")) { xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != "sensor"))) { if ((xml->name().toString() == "deadZone") && xml->isStartElement()) { QString temptext = xml->readElementText(); float tempchoice = temptext.toFloat(); setDeadZone(tempchoice); } else if ((xml->name().toString() == "maxZone") && xml->isStartElement()) { QString temptext = xml->readElementText(); float tempchoice = temptext.toFloat(); setMaxZone(tempchoice); } else if ((xml->name().toString() == "diagonalRange") && xml->isStartElement()) { QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); setDiagonalRange(tempchoice); } else if ((xml->name().toString() == GlobalVariables::JoySensorButton::xmlName) && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); JoySensorButton *button = m_buttons.value(static_cast(index)); QPointer joyButtonXml = new JoyButtonXml(button); if (button != nullptr) joyButtonXml->readConfig(xml); else xml->skipCurrentElement(); if (!joyButtonXml.isNull()) delete joyButtonXml; } else if ((xml->name().toString() == "sensorDelay") && xml->isStartElement()) { QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); setSensorDelay(tempchoice); } else { xml->skipCurrentElement(); } xml->readNextStartElement(); } } } /** * @brief Write the status of the properties of a sensor and direction buttons * to an XML stream. * @param QXmlStreamWriter instance that will be used to write a profile. */ void JoySensor::writeConfig(QXmlStreamWriter *xml) const { if (!isDefault()) { xml->writeStartElement("sensor"); xml->writeAttribute("type", QString::number(m_type)); if (!qFuzzyCompare(getDeadZone(), GlobalVariables::JoySensor::DEFAULTDEADZONE)) xml->writeTextElement("deadZone", QString::number(getDeadZone())); if (!qFuzzyCompare(getMaxZone(), (m_type == ACCELEROMETER ? GlobalVariables::JoySensor::ACCEL_MAX : GlobalVariables::JoySensor::GYRO_MAX))) xml->writeTextElement("maxZone", QString::number(getMaxZone())); if (!qFuzzyCompare(getDiagonalRange(), GlobalVariables::JoySensor::DEFAULTDIAGONALRANGE)) xml->writeTextElement("diagonalRange", QString::number(getDiagonalRange())); if (m_sensor_delay > GlobalVariables::JoySensor::DEFAULTSENSORDELAY) xml->writeTextElement("sensorDelay", QString::number(m_sensor_delay)); for (const auto &button : m_buttons) { JoyButtonXml *joyButtonXml = new JoyButtonXml(button); joyButtonXml->writeConfig(xml); delete joyButtonXml; joyButtonXml = nullptr; } xml->writeEndElement(); } } /** * @brief Get pointer to the set that a sensor belongs to. * @return Pointer to the set that a sensor belongs to. */ SetJoystick *JoySensor::getParentSet() const { return m_parent_set; } /** * @brief Slot called when m_delay_timer has timed out. The method will * call createDeskEvent. */ void JoySensor::delayTimerExpired() { createDeskEvent(calculateSensorDirection()); } /** * @brief Reset all the properties of the sensor direction buttons. */ void JoySensor::resetButtons() { for (const auto &button : m_buttons) { if (button != nullptr) button->reset(); } } /** * @brief Set buttons for current sensor direction zone. * * @param Pointer to an array of three JoySensorButton pointers in which * the results are stored. */ void JoySensor::determineSensorEvent(JoySensorButton **eventbutton) const { if (m_current_direction & SENSOR_LEFT) eventbutton[0] = m_buttons.value(SENSOR_LEFT); else if (m_current_direction & SENSOR_RIGHT) eventbutton[0] = m_buttons.value(SENSOR_RIGHT); if (m_current_direction & SENSOR_UP) eventbutton[1] = m_buttons.value(SENSOR_UP); else if (m_current_direction & SENSOR_DOWN) eventbutton[1] = m_buttons.value(SENSOR_DOWN); if (m_current_direction & SENSOR_FWD) eventbutton[2] = m_buttons.value(SENSOR_FWD); else if (m_current_direction & SENSOR_BWD) eventbutton[2] = m_buttons.value(SENSOR_BWD); } /** * @brief Find the position of the three sensor axes, deactivate no longer used * sensor direction button and then activate direction buttons for new * direction. * @param Should set changing operations be ignored. Necessary in the middle * of a set change. */ void JoySensor::createDeskEvent(JoySensorDirection direction, bool ignoresets) { m_current_direction = direction; JoySensorButton *eventbutton[ACTIVE_BUTTON_COUNT] = {nullptr}; determineSensorEvent(eventbutton); for (size_t i = 0; i < ACTIVE_BUTTON_COUNT; ++i) { if (m_active_button[i] != nullptr && m_active_button[i] != eventbutton[i]) { m_active_button[i]->joyEvent(false, ignoresets); m_active_button[i] = nullptr; } if (eventbutton[i] != nullptr && m_active_button[i] == nullptr) { m_active_button[i] = eventbutton[i]; m_active_button[i]->joyEvent(true, ignoresets); } else if (eventbutton[i] == nullptr && m_active_button[i] != nullptr) { m_active_button[i]->joyEvent(false, ignoresets); m_active_button[i] = nullptr; } } } AntiMicroX-antimicrox-b300273/src/joysensor.h000066400000000000000000000126531471077622000211540ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include #include #include #include "joysensordirection.h" #include "joysensortype.h" #include "pt1filter.h" class SetJoystick; class JoySensorButton; class QXmlStreamReader; class QXmlStreamWriter; /** * @brief Represents one sensor in a SetJoystick and its connections to * other parts of the application. * Receives hardware input events from InputDaemon, processes them and * generates GUI as well as Mouse+Keyboard events. */ class JoySensor : public QObject { Q_OBJECT public: explicit JoySensor(JoySensorType type, int originset, SetJoystick *parent_set, QObject *parent); virtual ~JoySensor(); void joyEvent(float *values, bool ignoresets = false); void queuePendingEvent(float *values, bool ignoresets = false); void activatePendingEvent(); bool hasPendingEvent() const; void clearPendingEvent(); void copyAssignments(JoySensor *dest_sensor); bool hasSlotsAssigned() const; QString getPartialName(bool forceFullFormat = false, bool displayNames = false) const; QString getSensorName() const; JoySensorType getType() const; JoySensorDirection getCurrentDirection() const; double getDeadZone() const; double getDiagonalRange() const; double getMaxZone() const; unsigned int getSensorDelay() const; virtual float getXCoordinate() const = 0; virtual float getYCoordinate() const = 0; virtual float getZCoordinate() const = 0; virtual QString sensorTypeName() const = 0; bool inDeadZone(float *values) const; double getDistanceFromDeadZone() const; double getDistanceFromDeadZone(double x, double y, double z) const; double calculateXDistanceFromDeadZone() const; double calculateXDistanceFromDeadZone(double x, double y, double z) const; double calculateYDistanceFromDeadZone() const; double calculateYDistanceFromDeadZone(double x, double y, double z) const; double calculateZDistanceFromDeadZone() const; double calculateZDistanceFromDeadZone(double x, double y, double z) const; double calculateDistance() const; double calculateDistance(double x, double y, double z) const; double calculatePitch() const; double calculatePitch(double x, double y, double z) const; double calculateRoll() const; double calculateRoll(double x, double y, double z) const; double calculateDirectionalDistance(JoySensorDirection direction) const; static double radToDeg(double value); static double degToRad(double value); bool isCalibrated() const; void resetCalibration(); virtual void getCalibration(double *offsetX, double *offsetY, double *offsetZ) const = 0; virtual void setCalibration(double offsetX, double offsetY, double offsetZ) = 0; QHash *getButtons(); JoySensorButton *getDirectionButton(JoySensorDirection direction); bool isDefault() const; void readConfig(QXmlStreamReader *xml); void writeConfig(QXmlStreamWriter *xml) const; SetJoystick *getParentSet() const; signals: void moved(float xaxis, float yaxis, float zaxis); void active(float xaxis, float yaxis, float zaxis); void released(float xaxis, float yaxis, float zaxis); void deadZoneChanged(double value); void diagonalRangeChanged(double value); void maxZoneChanged(double value); void sensorDelayChanged(int value); void sensorNameChanged(); void propertyUpdated(); public slots: virtual void reset(); void setDeadZone(double value); void setMaxZone(double value); void setDiagonalRange(double value); void setSensorDelay(unsigned int value); void setSensorName(QString tempName); void establishPropertyUpdatedConnection(); private slots: void delayTimerExpired(); protected: void resetButtons(); virtual void populateButtons() = 0; virtual JoySensorDirection calculateSensorDirection() = 0; virtual void applyCalibration() = 0; void determineSensorEvent(JoySensorButton **eventbutton) const; void createDeskEvent(JoySensorDirection direction, bool ignoresets = false); JoySensorType m_type; double m_dead_zone; double m_diagonal_range; double m_max_zone; unsigned int m_sensor_delay; bool m_active; static const size_t ACTIVE_BUTTON_COUNT = 3; JoySensorButton *m_active_button[ACTIVE_BUTTON_COUNT]; float m_current_value[3]; float m_pending_value[3]; bool m_calibrated; double m_calibration_value[3]; bool m_pending_event; bool m_pending_ignore_sets; int m_originset; QString m_sensor_name; QTimer m_delay_timer; JoySensorDirection m_current_direction; SetJoystick *m_parent_set; QHash m_buttons; }; AntiMicroX-antimicrox-b300273/src/joysensorbuttonpushbutton.cpp000066400000000000000000000071411471077622000250730ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joysensorbuttonpushbutton.h" #include "joybuttoncontextmenu.h" #include "joybuttontypes/joysensorbutton.h" #include "joysensor.h" #include #include #include JoySensorButtonPushButton::JoySensorButtonPushButton(JoySensorButton *button, bool displayNames, QWidget *parent) : FlashButtonWidget(displayNames, parent) , m_button(button) { refreshLabel(); enableFlashes(); tryFlash(); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &JoySensorButtonPushButton::customContextMenuRequested, this, &JoySensorButtonPushButton::showContextMenu); connect(m_button, &JoySensorButton::propertyUpdated, this, &JoySensorButtonPushButton::refreshLabel); connect(m_button, &JoySensorButton::activeZoneChanged, this, &JoySensorButtonPushButton::refreshLabel); } /** * @brief Get the JoySensorButton for this mapping */ JoySensorButton *JoySensorButtonPushButton::getButton() { return m_button; } /** * @brief Disables highlight when the sensor axis is moved */ void JoySensorButtonPushButton::disableFlashes() { if (m_button != nullptr) { disconnect(m_button, &JoySensorButton::clicked, this, &JoySensorButtonPushButton::flash); disconnect(m_button, &JoySensorButton::released, this, &JoySensorButtonPushButton::unflash); } unflash(); } /** * @brief Enables highlight when the sensor axis is moved */ void JoySensorButtonPushButton::enableFlashes() { if (m_button != nullptr) { connect(m_button, &JoySensorButton::clicked, this, &JoySensorButtonPushButton::flash, Qt::QueuedConnection); connect(m_button, &JoySensorButton::released, this, &JoySensorButtonPushButton::unflash, Qt::QueuedConnection); } } /** * @brief Generate the string that will be displayed on the button * @return Display string */ QString JoySensorButtonPushButton::generateLabel() { QString temp = QString(); if (m_button != nullptr) { if (!m_button->getActionName().isEmpty() && ifDisplayNames()) { qDebug() << "Action name was not empty"; temp = m_button->getActionName().replace("&", "&&"); } else { qDebug() << "Action name was empty"; temp = m_button->getCalculatedActiveZoneSummary().replace("&", "&&"); } } qDebug() << "Here is name of action for pushed sensor button: " << temp; return temp; } /** * @brief Shows sensor context menu */ void JoySensorButtonPushButton::showContextMenu(const QPoint &point) { QPoint globalPos = mapToGlobal(point); JoyButtonContextMenu *contextMenu = new JoyButtonContextMenu(m_button, this); contextMenu->buildMenu(); contextMenu->popup(globalPos); } /** * @brief Highlights the button when mapped button is active */ void JoySensorButtonPushButton::tryFlash() { if (m_button != nullptr && m_button->getButtonState()) flash(); } AntiMicroX-antimicrox-b300273/src/joysensorbuttonpushbutton.h000066400000000000000000000026701471077622000245420ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "flashbuttonwidget.h" class JoySensorButton; class QWidget; /** * @brief A direction button in the SensorPushButtonGroup */ class JoySensorButtonPushButton : public FlashButtonWidget { Q_OBJECT Q_PROPERTY(bool isflashing READ isButtonFlashing) public: explicit JoySensorButtonPushButton(JoySensorButton *button, bool displayNames, QWidget *parent = nullptr); JoySensorButton *getButton(); void tryFlash(); protected: virtual QString generateLabel() override; public slots: void disableFlashes() override; void enableFlashes() override; private slots: void showContextMenu(const QPoint &point); private: JoySensorButton *m_button; }; AntiMicroX-antimicrox-b300273/src/joysensorcontextmenu.cpp000066400000000000000000000047741471077622000240060ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joysensorcontextmenu.h" #include "common.h" #include "inputdevice.h" #include "joybuttontypes/joysensorbutton.h" #include "joysensor.h" #include "mousedialog/mousesensorsettingsdialog.h" #include #include #include #include JoySensorContextMenu::JoySensorContextMenu(JoySensor *sensor, QWidget *parent) : QMenu(parent) , m_sensor(sensor) , m_preset(sensor) { connect(this, &JoySensorContextMenu::aboutToHide, this, &JoySensorContextMenu::deleteLater); } /** * @brief Populates the context menu */ void JoySensorContextMenu::buildMenu() { QAction *action; QActionGroup *presetGroup = new QActionGroup(this); JoySensorPreset::Preset currentPreset = m_preset.currentPreset(); QList presets = m_preset.getAvailablePresets(); for (const auto &preset : presets) { action = addAction(m_preset.getPresetName(preset)); action->setCheckable(true); action->setChecked(currentPreset == preset); action->setData(QVariant(preset)); connect(action, &QAction::triggered, this, [this, action] { m_preset.setSensorPreset(static_cast(action->data().toInt())); }); presetGroup->addAction(action); } if (m_sensor->getType() == GYROSCOPE) { addSeparator(); action = addAction(tr("Mouse Settings")); action->setCheckable(false); connect(action, &QAction::triggered, this, &JoySensorContextMenu::openMouseSettingsDialog); } } /** * @brief Opens MouseSensorSettingsDialog from context menu */ void JoySensorContextMenu::openMouseSettingsDialog() { MouseSensorSettingsDialog *dialog = new MouseSensorSettingsDialog(m_sensor, parentWidget()); dialog->show(); } AntiMicroX-antimicrox-b300273/src/joysensorcontextmenu.h000066400000000000000000000023101471077622000234330ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "joysensorpreset.h" #include class JoySensor; class QWidget; /** * @brief The control stick context menu widget used by SensorPushButtonGroup */ class JoySensorContextMenu : public QMenu { Q_OBJECT public: explicit JoySensorContextMenu(JoySensor *sensor, QWidget *parent = nullptr); void buildMenu(); private slots: void openMouseSettingsDialog(); private: JoySensor *m_sensor; JoySensorPreset m_preset; }; AntiMicroX-antimicrox-b300273/src/joysensordirection.h000066400000000000000000000044701471077622000230530ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include /** * @brief A bitfield style enum which encodes all possible three dimensional * sensor directions. This allows triggering the mapped buttons by simply * checking the bits for the six basic directions. */ enum JoySensorDirection { SENSOR_CENTERED = 0, SENSOR_LEFT = (1 << 0), SENSOR_RIGHT = (1 << 1), SENSOR_UP = (1 << 2), SENSOR_DOWN = (1 << 3), SENSOR_FWD = (1 << 4), SENSOR_BWD = (1 << 5), SENSOR_LEFT_UP = SENSOR_LEFT | SENSOR_UP, SENSOR_LEFT_DOWN = SENSOR_LEFT | SENSOR_DOWN, SENSOR_LEFT_FWD = SENSOR_LEFT | SENSOR_FWD, SENSOR_LEFT_BWD = SENSOR_LEFT | SENSOR_BWD, SENSOR_RIGHT_UP = SENSOR_RIGHT | SENSOR_UP, SENSOR_RIGHT_DOWN = SENSOR_RIGHT | SENSOR_DOWN, SENSOR_RIGHT_FWD = SENSOR_RIGHT | SENSOR_FWD, SENSOR_RIGHT_BWD = SENSOR_RIGHT | SENSOR_BWD, SENSOR_UP_FWD = SENSOR_UP | SENSOR_FWD, SENSOR_UP_BWD = SENSOR_UP | SENSOR_BWD, SENSOR_DOWN_FWD = SENSOR_DOWN | SENSOR_FWD, SENSOR_DOWN_BWD = SENSOR_DOWN | SENSOR_BWD, SENSOR_LEFT_UP_FWD = SENSOR_LEFT | SENSOR_UP | SENSOR_FWD, SENSOR_LEFT_UP_BWD = SENSOR_LEFT | SENSOR_UP | SENSOR_BWD, SENSOR_LEFT_DOWN_FWD = SENSOR_LEFT | SENSOR_DOWN | SENSOR_FWD, SENSOR_LEFT_DOWN_BWD = SENSOR_LEFT | SENSOR_DOWN | SENSOR_BWD, SENSOR_RIGHT_UP_FWD = SENSOR_RIGHT | SENSOR_UP | SENSOR_FWD, SENSOR_RIGHT_UP_BWD = SENSOR_RIGHT | SENSOR_UP | SENSOR_BWD, SENSOR_RIGHT_DOWN_FWD = SENSOR_RIGHT | SENSOR_DOWN | SENSOR_FWD, SENSOR_RIGHT_DOWN_BWD = SENSOR_RIGHT | SENSOR_DOWN | SENSOR_BWD }; Q_DECLARE_METATYPE(JoySensorDirection) AntiMicroX-antimicrox-b300273/src/joysensorfactory.cpp000066400000000000000000000024131471077622000230700ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joysensorfactory.h" #include "joyaccelerometersensor.h" #include "joygyroscopesensor.h" #include "setjoystick.h" namespace JoySensorFactory { JoySensor *build(JoySensorType type, double rate, int originset, SetJoystick *parent_set, QObject *parent) { if (type == ACCELEROMETER) return new JoyAccelerometerSensor(rate, originset, parent_set, parent); else if (type == GYROSCOPE) return new JoyGyroscopeSensor(originset, parent_set, parent); else return nullptr; } } // namespace JoySensorFactory AntiMicroX-antimicrox-b300273/src/joysensorfactory.h000066400000000000000000000017071471077622000225420ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "joysensortype.h" class JoySensor; class SetJoystick; namespace JoySensorFactory { JoySensor *build(JoySensorType type, double rate, int originset, SetJoystick *parent_set, QObject *parent); } AntiMicroX-antimicrox-b300273/src/joysensorpreset.cpp000066400000000000000000000461261471077622000227340ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joysensorpreset.h" #include "antkeymapper.h" #include "common.h" #include "joybuttontypes/joysensorbutton.h" #include "joysensor.h" JoySensorPreset::JoySensorPreset(JoySensor *sensor, QObject *parent) : QObject(parent) , m_sensor(sensor) , m_helper(sensor) { m_helper.moveToThread(m_sensor->thread()); } /** * @brief Get available presets for the underlying sensor type * @returns QList of available presets */ QList JoySensorPreset::getAvailablePresets() { QList result; result.append(PRESET_NONE); if (m_sensor->getType() == ACCELEROMETER) { result.append(PRESET_ARROWS); result.append(PRESET_WASD); result.append(PRESET_NUMPAD); } else { result.append(PRESET_MOUSE); result.append(PRESET_MOUSE_INV_H); result.append(PRESET_MOUSE_INV_V); result.append(PRESET_MOUSE_INV_HV); } return result; } /** * @brief Determines the preset used by the underlying sensor * @returns The used preset if a preset is used or PRESET_NONE otherwise */ JoySensorPreset::Preset JoySensorPreset::currentPreset() { Preset result = PRESET_NONE; QList *leftslots, *rightslots, *upslots, *downslots, *fwdslots, *bwdslots; JoySensorButton *leftButton, *rightButton, *upButton, *downButton, *fwdButton, *bwdButton; PadderCommon::inputDaemonMutex.lock(); if (m_sensor->getType() == GYROSCOPE) { leftButton = m_sensor->getDirectionButton(SENSOR_LEFT); leftslots = leftButton->getAssignedSlots(); rightButton = m_sensor->getDirectionButton(SENSOR_RIGHT); rightslots = rightButton->getAssignedSlots(); upButton = m_sensor->getDirectionButton(SENSOR_UP); upslots = upButton->getAssignedSlots(); downButton = m_sensor->getDirectionButton(SENSOR_DOWN); downslots = downButton->getAssignedSlots(); fwdButton = m_sensor->getDirectionButton(SENSOR_FWD); fwdslots = fwdButton->getAssignedSlots(); bwdButton = m_sensor->getDirectionButton(SENSOR_BWD); bwdslots = bwdButton->getAssignedSlots(); if (upslots->length() == 1 && downslots->length() == 1 && leftslots->length() == 1 && rightslots->length() == 1 && fwdslots->length() == 1 && bwdslots->length() == 1) { JoyButtonSlot *upslot = upslots->at(0); JoyButtonSlot *downslot = downslots->at(0); JoyButtonSlot *leftslot = leftslots->at(0); JoyButtonSlot *rightslot = rightslots->at(0); JoyButtonSlot *fwdslot = fwdslots->at(0); JoyButtonSlot *bwdslot = bwdslots->at(0); if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseUp) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseDown) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseRight) && (fwdslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (bwdslot->getSlotCode() == JoyButtonSlot::MouseRight)) { result = PRESET_MOUSE; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseUp) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseDown) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseRight) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (fwdslot->getSlotCode() == JoyButtonSlot::MouseRight) && (bwdslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { result = PRESET_MOUSE_INV_H; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseDown) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseUp) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseRight) && (fwdslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (bwdslot->getSlotCode() == JoyButtonSlot::MouseRight)) { result = PRESET_MOUSE_INV_V; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (upslot->getSlotCode() == JoyButtonSlot::MouseDown) && (downslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (downslot->getSlotCode() == JoyButtonSlot::MouseUp) && (leftslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (leftslot->getSlotCode() == JoyButtonSlot::MouseRight) && (rightslot->getSlotMode() == JoyButtonSlot::JoyMouseMovement) && (rightslot->getSlotCode() == JoyButtonSlot::MouseLeft) && (fwdslot->getSlotCode() == JoyButtonSlot::MouseRight) && (bwdslot->getSlotCode() == JoyButtonSlot::MouseLeft)) { result = PRESET_MOUSE_INV_HV; } } } else { leftButton = m_sensor->getDirectionButton(SENSOR_LEFT); leftslots = leftButton->getAssignedSlots(); rightButton = m_sensor->getDirectionButton(SENSOR_RIGHT); rightslots = rightButton->getAssignedSlots(); upButton = m_sensor->getDirectionButton(SENSOR_UP); upslots = upButton->getAssignedSlots(); downButton = m_sensor->getDirectionButton(SENSOR_DOWN); downslots = downButton->getAssignedSlots(); bwdButton = m_sensor->getDirectionButton(SENSOR_BWD); bwdslots = bwdButton->getAssignedSlots(); if (upslots->length() == 1 && downslots->length() == 1 && leftslots->length() == 1 && rightslots->length() == 1 && bwdslots->length() == 0) { JoyButtonSlot *upslot = upslots->at(0); JoyButtonSlot *downslot = downslots->at(0); JoyButtonSlot *leftslot = leftslots->at(0); JoyButtonSlot *rightslot = rightslots->at(0); if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right))) { result = PRESET_ARROWS; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D))) { result = PRESET_WASD; } else if ((upslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (upslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8)) && (downslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (downslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2)) && (leftslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (leftslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4)) && (rightslot->getSlotMode() == JoyButtonSlot::JoyKeyboard) && (rightslot->getSlotCode() == AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6))) { result = PRESET_NUMPAD; } } } PadderCommon::inputDaemonMutex.unlock(); return result; } /** * @brief Get the translated name of a given preset * @returns Translated preset name */ QString JoySensorPreset::getPresetName(Preset preset) { QString result; switch (preset) { case PRESET_NONE: result = tr("None"); break; case PRESET_MOUSE: result = tr("Mouse (Normal)"); break; case PRESET_MOUSE_INV_H: result = tr("Mouse (Inverted Horizontal)"); break; case PRESET_MOUSE_INV_V: result = tr("Mouse (Inverted Vertical)"); break; case PRESET_MOUSE_INV_HV: result = tr("Mouse (Inverted Horizontal + Vertical)"); break; case PRESET_ARROWS: result = tr("Arrows"); break; case PRESET_WASD: result = tr("Keys: W | A | S | D"); break; case PRESET_NUMPAD: result = tr("NumPad"); break; } return result; } /** * @brief Assigns given preset to the underlying sensor * This function defines the preset mappings and sensor parameters. * @param[in] preset The preset to assign */ void JoySensorPreset::setSensorPreset(Preset preset) { JoyButtonSlot *leftButtonSlot = nullptr; JoyButtonSlot *rightButtonSlot = nullptr; JoyButtonSlot *upButtonSlot = nullptr; JoyButtonSlot *downButtonSlot = nullptr; JoyButtonSlot *fwdButtonSlot = nullptr; JoyButtonSlot *bwdButtonSlot = nullptr; switch (preset) { case PRESET_NONE: QMetaObject::invokeMethod(&m_helper, "clearButtonsSlotsEventReset"); QMetaObject::invokeMethod(m_sensor, "setDiagonalRange", Q_ARG(double, 45)); break; case PRESET_MOUSE: leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); fwdButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); bwdButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); QMetaObject::invokeMethod(m_sensor, "setDeadZone", Q_ARG(double, 0)); QMetaObject::invokeMethod(m_sensor, "setDiagonalRange", Q_ARG(double, 90)); break; case PRESET_MOUSE_INV_H: leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); fwdButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); bwdButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); QMetaObject::invokeMethod(m_sensor, "setDeadZone", Q_ARG(double, 0)); QMetaObject::invokeMethod(m_sensor, "setDiagonalRange", Q_ARG(double, 90)); break; case PRESET_MOUSE_INV_V: leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); fwdButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); bwdButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); QMetaObject::invokeMethod(m_sensor, "setDeadZone", Q_ARG(double, 0)); QMetaObject::invokeMethod(m_sensor, "setDiagonalRange", Q_ARG(double, 90)); break; case PRESET_MOUSE_INV_HV: leftButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); rightButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); upButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); downButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); fwdButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); bwdButtonSlot = new JoyButtonSlot(JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); QMetaObject::invokeMethod(m_sensor, "setDeadZone", Q_ARG(double, 0)); QMetaObject::invokeMethod(m_sensor, "setDiagonalRange", Q_ARG(double, 90)); break; case PRESET_ARROWS: leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Left), Qt::Key_Left, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Right), Qt::Key_Right, JoyButtonSlot::JoyKeyboard, this); upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Up), Qt::Key_Up, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Down), Qt::Key_Down, JoyButtonSlot::JoyKeyboard, this); QMetaObject::invokeMethod(m_sensor, "setDeadZone", Q_ARG(double, 15)); QMetaObject::invokeMethod(m_sensor, "setDiagonalRange", Q_ARG(double, 45)); break; case PRESET_WASD: leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_A), Qt::Key_A, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_D), Qt::Key_D, JoyButtonSlot::JoyKeyboard, this); upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_W), Qt::Key_W, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_S), Qt::Key_S, JoyButtonSlot::JoyKeyboard, this); QMetaObject::invokeMethod(m_sensor, "setDeadZone", Q_ARG(double, 15)); QMetaObject::invokeMethod(m_sensor, "setDiagonalRange", Q_ARG(double, 45)); break; case PRESET_NUMPAD: leftButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_4), QtKeyMapperBase::AntKey_KP_4, JoyButtonSlot::JoyKeyboard, this); rightButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_6), QtKeyMapperBase::AntKey_KP_6, JoyButtonSlot::JoyKeyboard, this); upButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_8), QtKeyMapperBase::AntKey_KP_8, JoyButtonSlot::JoyKeyboard, this); downButtonSlot = new JoyButtonSlot(AntKeyMapper::getInstance()->returnVirtualKey(QtKeyMapperBase::AntKey_KP_2), QtKeyMapperBase::AntKey_KP_2, JoyButtonSlot::JoyKeyboard, this); QMetaObject::invokeMethod(m_sensor, "setDeadZone", Q_ARG(double, 15)); QMetaObject::invokeMethod(m_sensor, "setDiagonalRange", Q_ARG(double, 45)); break; } QHash tempHash; if (upButtonSlot != nullptr) tempHash.insert(SENSOR_UP, upButtonSlot); if (downButtonSlot != nullptr) tempHash.insert(SENSOR_DOWN, downButtonSlot); if (leftButtonSlot != nullptr) tempHash.insert(SENSOR_LEFT, leftButtonSlot); if (rightButtonSlot != nullptr) tempHash.insert(SENSOR_RIGHT, rightButtonSlot); if (fwdButtonSlot != nullptr) tempHash.insert(SENSOR_FWD, fwdButtonSlot); if (bwdButtonSlot != nullptr) tempHash.insert(SENSOR_BWD, bwdButtonSlot); m_helper.setPendingSlots(&tempHash); QMetaObject::invokeMethod(&m_helper, "setFromPendingSlots", Qt::BlockingQueuedConnection); } /** * @brief Get the internal JoySensorIoThreadHelper */ JoySensorIoThreadHelper &JoySensorPreset::getHelper() { return m_helper; } AntiMicroX-antimicrox-b300273/src/joysensorpreset.h000066400000000000000000000027111471077622000223710ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "uihelpers/joysensoriothreadhelper.h" /** * @brief Defines presets for a sensor */ class JoySensorPreset : public QObject { Q_OBJECT public: enum Preset { PRESET_NONE, PRESET_MOUSE, PRESET_MOUSE_INV_H, PRESET_MOUSE_INV_V, PRESET_MOUSE_INV_HV, PRESET_ARROWS, PRESET_WASD, PRESET_NUMPAD }; explicit JoySensorPreset(JoySensor *sensor, QObject *parent = nullptr); QList getAvailablePresets(); Preset currentPreset(); QString getPresetName(Preset); void setSensorPreset(Preset); JoySensorIoThreadHelper &getHelper(); private: JoySensor *m_sensor; JoySensorIoThreadHelper m_helper; }; AntiMicroX-antimicrox-b300273/src/joysensorpushbutton.cpp000066400000000000000000000062351471077622000236420ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joysensorpushbutton.h" #include "joysensor.h" #include "joysensorcontextmenu.h" #include JoySensorPushButton::JoySensorPushButton(JoySensor *sensor, bool displayNames, QWidget *parent) : FlashButtonWidget(displayNames, parent) , m_sensor(sensor) { refreshLabel(); tryFlash(); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &JoySensorPushButton::customContextMenuRequested, this, &JoySensorPushButton::showContextMenu); connect(m_sensor, &JoySensor::active, this, &JoySensorPushButton::flash, Qt::QueuedConnection); connect(m_sensor, &JoySensor::released, this, &JoySensorPushButton::unflash, Qt::QueuedConnection); connect(m_sensor, &JoySensor::sensorNameChanged, this, &JoySensorPushButton::refreshLabel); } /** * @brief Get the underlying JoySensor object. */ JoySensor *JoySensorPushButton::getSensor() const { return m_sensor; } /** * @brief Generate the string that will be displayed on the button * @return Display string */ QString JoySensorPushButton::generateLabel() { QString temp = QString(); if (!m_sensor->getSensorName().isEmpty() && ifDisplayNames()) temp.append(m_sensor->getPartialName(false, true)); else temp.append(m_sensor->getPartialName(false)); qDebug() << "Name of joy sensor push button: " << temp; return temp; } /** * @brief Disables highlight when the sensor axis is moved */ void JoySensorPushButton::disableFlashes() { disconnect(m_sensor, &JoySensor::active, this, &JoySensorPushButton::flash); disconnect(m_sensor, &JoySensor::released, this, &JoySensorPushButton::unflash); unflash(); } /** * @brief Enables highlight when the sensor axis is moved */ void JoySensorPushButton::enableFlashes() { connect(m_sensor, &JoySensor::active, this, &JoySensorPushButton::flash, Qt::QueuedConnection); connect(m_sensor, &JoySensor::released, this, &JoySensorPushButton::unflash, Qt::QueuedConnection); } /** * @brief Shows sensor context menu */ void JoySensorPushButton::showContextMenu(const QPoint &point) { QPoint globalPos = mapToGlobal(point); JoySensorContextMenu *contextMenu = new JoySensorContextMenu(m_sensor, this); contextMenu->buildMenu(); contextMenu->popup(globalPos); } /** * @brief Highlights the button when sensor is not centered */ void JoySensorPushButton::tryFlash() { if (m_sensor->getCurrentDirection() != JoySensorDirection::SENSOR_CENTERED) flash(); } AntiMicroX-antimicrox-b300273/src/joysensorpushbutton.h000066400000000000000000000025421471077622000233040ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "flashbuttonwidget.h" class JoySensor; class QWidget; /** * @brief The central button in a SensorPushButtonGroup */ class JoySensorPushButton : public FlashButtonWidget { Q_OBJECT public: explicit JoySensorPushButton(JoySensor *sensor, bool displayNames, QWidget *parent = nullptr); JoySensor *getSensor() const; void tryFlash(); protected: virtual QString generateLabel() override; public slots: void disableFlashes() override; void enableFlashes() override; private slots: void showContextMenu(const QPoint &point); private: JoySensor *m_sensor; }; AntiMicroX-antimicrox-b300273/src/joysensorstatusbox.cpp000066400000000000000000000175721471077622000234710ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joysensorstatusbox.h" #include "common.h" #include "globalvariables.h" #include "joyaxis.h" #include "joysensor.h" #include #include #include #include #include #include #include #include JoySensorStatusBox::JoySensorStatusBox(QWidget *parent) : QWidget(parent) , m_sensor(nullptr) { } /** * @brief Sets the to be visualized sensor. * * It disconnects all events to the previous sensor if there was any, and * connects them to the new sensor. */ void JoySensorStatusBox::setSensor(JoySensor *sensor) { if (m_sensor != nullptr) { disconnect(m_sensor, SIGNAL(deadZoneChanged(double)), this, nullptr); disconnect(m_sensor, SIGNAL(moved(float, float, float)), this, nullptr); disconnect(m_sensor, SIGNAL(diagonalRangeChanged(double)), this, nullptr); disconnect(m_sensor, SIGNAL(maxZoneChanged(double)), this, nullptr); } m_sensor = sensor; connect(m_sensor, SIGNAL(deadZoneChanged(double)), this, SLOT(update())); connect(m_sensor, SIGNAL(moved(float, float, float)), this, SLOT(update())); connect(m_sensor, SIGNAL(diagonalRangeChanged(double)), this, SLOT(update())); connect(m_sensor, SIGNAL(maxZoneChanged(double)), this, SLOT(update())); update(); } /** * @brief Get the visualized sensor object */ JoySensor *JoySensorStatusBox::getSensor() const { return m_sensor; } QSize JoySensorStatusBox::sizeHint() const { return QSize(-1, -1); } void JoySensorStatusBox::paintEvent(QPaintEvent *event) { Q_UNUSED(event); PadderCommon::inputDaemonMutex.lock(); drawArtificialHorizon(); PadderCommon::inputDaemonMutex.unlock(); } /** * @brief draws the artificial horizon instrument on the screen */ void JoySensorStatusBox::drawArtificialHorizon() { QPainter paint(this); paint.setRenderHint(QPainter::Antialiasing, true); int side = qMin(width(), height()); QPen pen; QPixmap pix(side, side); pix.fill(Qt::transparent); QPainter painter(&pix); painter.setRenderHint(QPainter::Antialiasing, true); // Switch to centric coordinate system painter.translate(side / 2.0, side / 2.0); painter.scale(side * 0.45, -side * 0.45); painter.save(); // Draw moving instrument parts QPainterPath clippingPath; clippingPath.addEllipse(QPointF(0, 0), 1, 1); painter.setClipPath(clippingPath); JoySensorType type; double pitch, roll, yaw; if (m_sensor != nullptr) { type = m_sensor->getType(); if (type == ACCELEROMETER) { pitch = -JoySensor::radToDeg(m_sensor->calculatePitch()); roll = JoySensor::radToDeg(m_sensor->calculateRoll()); yaw = 0; } else { pitch = -m_sensor->getXCoordinate(); roll = m_sensor->getYCoordinate(); yaw = -m_sensor->getZCoordinate(); } } else { type = ACCELEROMETER; pitch = 0; roll = 0; yaw = 0; } pitch = qBound(-180.0, pitch, 180.0); roll = qBound(-180.0, roll, 180.0); yaw = qBound(-180.0, yaw, 180.0); painter.translate(yaw / 90, pitch / 90); painter.rotate(roll); pen.setColor(Qt::transparent); painter.setPen(pen); painter.setBrush(QBrush(QColor(64, 128, 255))); painter.drawRect(QRectF(-10, 0, 20, 10)); painter.setBrush(QBrush(Qt::black)); painter.drawRect(QRectF(-10, -10, 20, 10)); // Draw dead zone pen.setColor(Qt::red); pen.setWidthF(0.02); painter.setPen(pen); painter.setBrush(QBrush(QColor(255, 0, 0, 128))); double deadZone = m_sensor != nullptr ? m_sensor->getDeadZone() : 0.0; painter.drawEllipse(QPointF(0, 0), deadZone / 90, deadZone / 90); // Draw max zone QPainterPath maxZonePath; double maxZone = m_sensor != nullptr ? m_sensor->getMaxZone() : 0.0; maxZonePath.addEllipse(QPointF(0, 0), 10, 10); maxZonePath.addEllipse(QPointF(0, 0), maxZone / 90, maxZone / 90); pen.setColor(Qt::darkGreen); pen.setWidthF(0.02); painter.setPen(pen); painter.setBrush(QBrush(QColor(0, 128, 0, 128))); painter.drawPath(maxZonePath); // Draw diagonal zones pen.setColor(Qt::green); painter.setPen(pen); painter.setBrush(QBrush(QColor(0, 255, 0, 128))); double diagonalRange = m_sensor != nullptr ? m_sensor->getDiagonalRange() : 0.0; if (type == GYROSCOPE) { for (int i = 0; i < 4; ++i) { painter.drawPie(QRectF(-maxZone / 90, -maxZone / 90, 2 * maxZone / 90, 2 * maxZone / 90), (45 + 90 * i - diagonalRange / 2) * 16, diagonalRange * 16); } } else { painter.drawPie(QRectF(-maxZone / 90, -maxZone / 90, 2 * maxZone / 90, 2 * maxZone / 90), (135 - diagonalRange / 2) * 16, (diagonalRange + 90) * 16); painter.drawPie(QRectF(-maxZone / 90, -maxZone / 90, 2 * maxZone / 90, 2 * maxZone / 90), (-45 - diagonalRange / 2) * 16, (diagonalRange + 90) * 16); } // Pitch scale: 30deg per line pen.setColor(Qt::white); pen.setWidthF(0.025); painter.setPen(pen); painter.setBrush(QBrush(Qt::transparent)); for (int j = -180; j <= 180; j += 30) { painter.drawLine(QPointF(-10, j / 90.0), QPointF(10, j / 90.0)); } // Yaw scale: 30deg per line if (type == GYROSCOPE) { pen.setColor(Qt::white); pen.setWidthF(0.025); painter.setPen(pen); painter.setBrush(QBrush(Qt::transparent)); for (int j = -180; j <= 180; j += 30) { painter.drawLine(QPointF(j / 90.0, -10), QPointF(j / 90.0, 10)); } } // Draw fixed instrument parts painter.restore(); painter.save(); pen.setColor(QColor(80, 80, 80)); pen.setWidthF(0.2); painter.setPen(pen); painter.setBrush(Qt::NoBrush); painter.drawEllipse(QPointF(0, 0), 1, 1); // Draw scale pen.setWidthF(0.05); pen.setColor(Qt::yellow); painter.setPen(pen); painter.drawLine(QPointF(0.3, 0), QPointF(0.2, 0)); painter.drawLine(QPointF(-0.3, 0), QPointF(-0.2, 0)); painter.drawArc(QRectF(-0.2, -0.2, 0.4, 0.4), 0 * 16, 180 * 16); painter.drawPoint(QPointF(0, 0)); pen.setColor(Qt::white); painter.setPen(pen); for (int j = 0; j < 19; ++j) { painter.drawLine(QPointF(1, 0), QPointF(0.9, 0)); painter.rotate(10.0); } // Draw dead zone painter.restore(); pen.setColor(Qt::red); pen.setWidthF(0.1); painter.setPen(pen); painter.setOpacity(0.5); painter.drawArc(QRectF(-1, -1, 2, 2), -16 * deadZone, 16 * deadZone * 2); painter.drawArc(QRectF(-1, -1, 2, 2), 16 * (180 - deadZone), 16 * deadZone * 2); // Draw max zone pen.setColor(Qt::darkGreen); painter.setPen(pen); double tmpMaxZone = std::min(maxZone, 90.0); painter.drawArc(QRectF(-1, -1, 2, 2), 16 * (90 - (90 - tmpMaxZone)), 16 * (90 - tmpMaxZone) * 2); painter.drawArc(QRectF(-1, -1, 2, 2), 16 * (270 - (90 - tmpMaxZone)), 16 * (90 - tmpMaxZone) * 2); // Draw to window paint.setCompositionMode(QPainter::CompositionMode_SourceOver); paint.drawPixmap(pix.rect(), pix); } AntiMicroX-antimicrox-b300273/src/joysensorstatusbox.h000066400000000000000000000026631471077622000231310ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include #include class JoySensor; class QPaintEvent; /** * @brief The GUI sensor position indicator widget * * It shows the yaw and roll angles on an artificial horizon instrument. * In case of a gyroscope, the inner parts has an additional horizontal * degree of freedom. */ class JoySensorStatusBox : public QWidget { Q_OBJECT public: explicit JoySensorStatusBox(QWidget *parent = nullptr); void setSensor(JoySensor *sensor); JoySensor *getSensor() const; virtual QSize sizeHint() const override; protected: virtual void paintEvent(QPaintEvent *event) override; void drawArtificialHorizon(); private: JoySensor *m_sensor; }; AntiMicroX-antimicrox-b300273/src/joysensortype.h000066400000000000000000000017311471077622000220510ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include #include enum JoySensorType { ACCELEROMETER, GYROSCOPE, #if SDL_VERSION_ATLEAST(2, 0, 14) SENSOR_COUNT #else SENSOR_COUNT = 0 #endif }; Q_DECLARE_METATYPE(JoySensorType) AntiMicroX-antimicrox-b300273/src/joystick.cpp000066400000000000000000000110631471077622000213050ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joystick.h" #include "antimicrosettings.h" #include "globalvariables.h" #include #include #include #include #include Joystick::Joystick(SDL_Joystick *joyhandle, int deviceIndex, AntiMicroSettings *settings, QObject *parent) : InputDevice(joyhandle, deviceIndex, settings, parent) { m_joyhandle = joyhandle; controller = SDL_GameControllerOpen(deviceIndex); joystickID = SDL_JoystickInstanceID(joyhandle); for (int i = 0; i < GlobalVariables::InputDevice::NUMBER_JOYSETS; i++) { SetJoystick *setstick = new SetJoystick(this, i, this); getJoystick_sets().insert(i, setstick); enableSetConnections(setstick); } INFO() << "Created new Joystick:\n" << getDescription(); } QString Joystick::getXmlName() const { return GlobalVariables::Joystick::xmlName; } QString Joystick::getName() { return QString(tr("Joystick")).append(" ").append(QString::number(getRealJoyNumber())); } QString Joystick::getSDLName() { QString temp = QString(); if (m_joyhandle != nullptr) { temp = SDL_JoystickName(m_joyhandle); } return temp; } QString Joystick::getGUIDString() const { QString temp = QString(); SDL_JoystickGUID tempGUID = SDL_JoystickGetGUID(m_joyhandle); char guidString[65] = {'0'}; SDL_JoystickGetGUIDString(tempGUID, guidString, sizeof(guidString)); temp = QString(guidString); // Not available on SDL 1.2. Return empty string in that case. return temp; } QString Joystick::getVendorString() const { QString temp = QString(); if (m_joyhandle != nullptr) { Uint16 tempVendor = SDL_JoystickGetVendor(m_joyhandle); char buffer[50]; sprintf(buffer, "%u", tempVendor); temp = QString(buffer); } return temp; } QString Joystick::getProductIDString() const { QString temp = QString(); if (m_joyhandle != nullptr) { Uint16 tempProduct = SDL_JoystickGetProduct(m_joyhandle); char buffer[50]; sprintf(buffer, "%u", tempProduct); temp = QString(buffer); } return temp; } QString Joystick::getSerialString() const { QString temp = QString(); #if SDL_VERSION_ATLEAST(2, 0, 14) if (m_joyhandle != nullptr) { const char *serial = SDL_JoystickGetSerial(m_joyhandle); temp = QString(serial).remove(QRegularExpression("[^A-Za-z0-9]")); } #endif return temp; } QString Joystick::getProductVersion() const { QString temp = QString(); if (m_joyhandle != nullptr) { Uint16 tempProductVersion = SDL_JoystickGetProductVersion(m_joyhandle); char buffer[50]; sprintf(buffer, "%u", tempProductVersion); temp = QString(buffer); } return temp; } QString Joystick::getUniqueIDString() const { return (getGUIDString() + getVendorString() + getProductIDString()) + getSerialString(); } void Joystick::closeSDLDevice() { if ((m_joyhandle != nullptr) && SDL_JoystickGetAttached(m_joyhandle)) { SDL_JoystickClose(m_joyhandle); } } int Joystick::getNumberRawButtons() { int numbuttons = SDL_JoystickNumButtons(m_joyhandle); return numbuttons; } int Joystick::getNumberRawAxes() { int numaxes = SDL_JoystickNumAxes(m_joyhandle); return numaxes; } int Joystick::getNumberRawHats() { int numhats = SDL_JoystickNumHats(m_joyhandle); return numhats; } double Joystick::getRawSensorRate(JoySensorType _) { return 0; } bool Joystick::hasRawSensor(JoySensorType _) { return false; } void Joystick::setCounterUniques(int counter) { counterUniques = counter; } SDL_JoystickID Joystick::getSDLJoystickID() { return joystickID; } SDL_Joystick *Joystick::getJoyhandle() const { return m_joyhandle; } AntiMicroX-antimicrox-b300273/src/joystick.h000066400000000000000000000050221471077622000207500ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYSTICK_H #define JOYSTICK_H #include "inputdevice.h" #include class AntiMicroSettings; /** * @brief General input device (which is not a typical gamepad like steering wheels, flight sticks etc.) * * @details This is broad category of devices. (Includes Gamepads described by GameController and all of the other devices) * Devices in this category trigger events SDL_JOY... (like SDL_JOYBUTTONUP) */ class Joystick : public InputDevice { Q_OBJECT public: explicit Joystick(SDL_Joystick *joyhandle, int deviceIndex, AntiMicroSettings *settings, QObject *parent); virtual QString getName() override; virtual QString getSDLName() override; virtual QString getGUIDString() const override; // GUID available on SDL 2. virtual QString getUniqueIDString() const override; virtual QString getVendorString() const override; virtual QString getProductIDString() const override; virtual QString getSerialString() const override; virtual QString getProductVersion() const override; virtual void closeSDLDevice() override; virtual SDL_JoystickID getSDLJoystickID() override; virtual int getNumberRawButtons() override; virtual int getNumberRawAxes() override; virtual int getNumberRawHats() override; virtual double getRawSensorRate(JoySensorType type) override; virtual bool hasRawSensor(JoySensorType type) override; void setCounterUniques(int counter) override; SDL_Joystick *getJoyhandle() const; virtual QString getXmlName() const override; private: SDL_Joystick *m_joyhandle; SDL_GameController *controller; SDL_JoystickID joystickID; int counterUniques; }; Q_DECLARE_METATYPE(Joystick *) #endif // JOYSTICK_H AntiMicroX-antimicrox-b300273/src/keyboard/000077500000000000000000000000001471077622000205415ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/keyboard/virtualkeyboardmousewidget.cpp000066400000000000000000001253341471077622000267410ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "virtualkeyboardmousewidget.h" #include "antkeymapper.h" #include "buttoneditdialog.h" #include "event.h" #include "mousedialog/mousebuttonsettingsdialog.h" #include "qtkeymapperbase.h" #include "quicksetdialog.h" #include "virtualkeypushbutton.h" #include "virtualmousepushbutton.h" #include #ifdef WITH_X11 #include "x11extras.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include QHash VirtualKeyboardMouseWidget::topRowKeys = QHash(); VirtualKeyboardMouseWidget::VirtualKeyboardMouseWidget(InputDevice *joystick, ButtonEditDialogHelper *helper, bool isNumKeypad, QuickSetDialog *quickSetDialog, JoyButton *button, QWidget *parent) : QTabWidget(parent) { m_isNumKeypad = isNumKeypad; this->joystick = joystick; this->helper = helper; this->withoutQuickSetDialog = (button != nullptr); lastPressedBtn = button; currentQuickDialog = quickSetDialog; keyboardTab = new QWidget(this); mouseTab = new QWidget(this); noneButton = createNoneKey(); populateTopRowKeys(); this->addTab(keyboardTab, tr("Keyboard")); this->addTab(mouseTab, tr("Mouse")); this->setTabPosition(QTabWidget::South); setupVirtualKeyboardLayout(); setupMouseControlLayout(); establishVirtualKeyboardSingleSignalConnections(); establishVirtualMouseSignalConnections(); QTimer::singleShot(0, this, SLOT(setButtonFontSizes())); connect(mouseSettingsPushButton, &QPushButton::clicked, this, &VirtualKeyboardMouseWidget::openMouseSettingsDialog); } VirtualKeyboardMouseWidget::VirtualKeyboardMouseWidget(bool isNumKeypad, QWidget *parent) : QTabWidget(parent) { m_isNumKeypad = isNumKeypad; keyboardTab = new QWidget(this); mouseTab = new QWidget(this); noneButton = createNoneKey(); withoutQuickSetDialog = false; lastPressedBtn = nullptr; populateTopRowKeys(); this->addTab(keyboardTab, tr("Keyboard")); this->addTab(mouseTab, tr("Mouse")); this->setTabPosition(QTabWidget::South); setupVirtualKeyboardLayout(); setupMouseControlLayout(); establishVirtualKeyboardSingleSignalConnections(); establishVirtualMouseSignalConnections(); QTimer::singleShot(0, this, SLOT(setButtonFontSizes())); } /*bool VirtualKeyboardMouseWidget::is_numlock_activated() { #if defined(WITH_X11) Display *dpy = XOpenDisplay(X11Extras::getInstance()->getEnvVariable("DISPLAY")); XKeyboardState x; XGetKeyboardControl(dpy, &x); XCloseDisplay(dpy); return x.led_mask & 2; #endif return false; } bool VirtualKeyboardMouseWidget::isLaptop() { int secs, pct; if (SDL_GetPowerInfo(&secs, &pct) == SDL_POWERSTATE_UNKNOWN) return false; else return true; }*/ void VirtualKeyboardMouseWidget::setupVirtualKeyboardLayout() { QVBoxLayout *finalVBoxLayout = new QVBoxLayout(keyboardTab); QVBoxLayout *tempMainKeyLayout = setupMainKeyboardLayout(); QVBoxLayout *tempAuxKeyLayout = new QVBoxLayout(); QVBoxLayout *tempNumKeyPadLayout = new QVBoxLayout(); if (m_isNumKeypad) { tempNumKeyPadLayout = setupKeyboardNumPadLayout(); } else { QPushButton *othersKeysButton = createOtherKeysMenu(); tempNumKeyPadLayout->addWidget(noneButton); tempNumKeyPadLayout->addWidget(othersKeysButton); tempNumKeyPadLayout->addSpacerItem(new QSpacerItem(0, 20, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding)); } QHBoxLayout *tempHBoxLayout = new QHBoxLayout(); tempHBoxLayout->addLayout(tempMainKeyLayout); if (m_isNumKeypad) { tempAuxKeyLayout = setupAuxKeyboardLayout(); tempHBoxLayout->addLayout(tempAuxKeyLayout); } else { delete tempAuxKeyLayout; } tempHBoxLayout->addLayout(tempNumKeyPadLayout); finalVBoxLayout->addLayout(tempHBoxLayout); } QVBoxLayout *VirtualKeyboardMouseWidget::setupMainKeyboardLayout() { QHBoxLayout *tempHBoxLayout = new QHBoxLayout(); tempHBoxLayout->setSpacing(0); QVBoxLayout *tempVBoxLayout = new QVBoxLayout(); tempVBoxLayout->setSpacing(0); QVBoxLayout *finalVBoxLayout = new QVBoxLayout(); if (!m_isNumKeypad) finalVBoxLayout->setSpacing(0); tempHBoxLayout->addWidget(createNewKey("Escape")); if (m_isNumKeypad) tempHBoxLayout->addSpacerItem(new QSpacerItem(70, 10, QSizePolicy::Expanding)); tempHBoxLayout->addWidget(createNewKey("F1")); tempHBoxLayout->addWidget(createNewKey("F2")); tempHBoxLayout->addWidget(createNewKey("F3")); tempHBoxLayout->addWidget(createNewKey("F4")); if (m_isNumKeypad) tempHBoxLayout->addSpacerItem(new QSpacerItem(70, 10, QSizePolicy::Expanding)); tempHBoxLayout->addWidget(createNewKey("F5")); tempHBoxLayout->addWidget(createNewKey("F6")); tempHBoxLayout->addWidget(createNewKey("F7")); tempHBoxLayout->addWidget(createNewKey("F8")); if (m_isNumKeypad) tempHBoxLayout->addSpacerItem(new QSpacerItem(70, 10, QSizePolicy::Expanding)); tempHBoxLayout->addWidget(createNewKey("F9")); tempHBoxLayout->addWidget(createNewKey("F10")); tempHBoxLayout->addWidget(createNewKey("F11")); tempHBoxLayout->addWidget(createNewKey("F12")); if (!m_isNumKeypad) { tempHBoxLayout->addWidget(createNewKey("Print")); tempHBoxLayout->addWidget(createNewKey("Pause")); tempHBoxLayout->addWidget(createNewKey("Delete")); } finalVBoxLayout->addLayout(tempHBoxLayout); if (m_isNumKeypad) finalVBoxLayout->addSpacerItem(new QSpacerItem(20, 35, QSizePolicy::Minimum, QSizePolicy::Fixed)); tempHBoxLayout = new QHBoxLayout(); tempHBoxLayout->setSpacing(0); tempHBoxLayout->addWidget(createNewKey("grave")); for (int i = 1; i <= 9; i++) { tempHBoxLayout->addWidget(createNewKey(QString::number(i))); } tempHBoxLayout->addWidget(createNewKey("0")); tempHBoxLayout->addWidget(createNewKey("minus")); tempHBoxLayout->addWidget(createNewKey("equal")); tempHBoxLayout->addWidget(createNewKey("BackSpace")); if (!m_isNumKeypad) { tempHBoxLayout->addWidget(createNewKey("Home")); } tempVBoxLayout->addLayout(tempHBoxLayout); QVBoxLayout *tempMiddleVLayout = new QVBoxLayout(); tempMiddleVLayout->setSpacing(0); QHBoxLayout *tempMiddleHLayout = new QHBoxLayout(); tempHBoxLayout = new QHBoxLayout(); tempHBoxLayout->addWidget(createNewKey("Tab")); if (m_isNumKeypad) tempHBoxLayout->addSpacerItem(new QSpacerItem(10, 30, QSizePolicy::Fixed)); tempHBoxLayout->addWidget(createNewKey("q")); tempHBoxLayout->addWidget(createNewKey("w")); tempHBoxLayout->addWidget(createNewKey("e")); tempHBoxLayout->addWidget(createNewKey("r")); tempHBoxLayout->addWidget(createNewKey("t")); tempHBoxLayout->addWidget(createNewKey("y")); tempHBoxLayout->addWidget(createNewKey("u")); tempHBoxLayout->addWidget(createNewKey("i")); tempHBoxLayout->addWidget(createNewKey("o")); tempHBoxLayout->addWidget(createNewKey("p")); tempHBoxLayout->addWidget(createNewKey("bracketleft")); tempHBoxLayout->addWidget(createNewKey("bracketright")); if ((QLocale::system().language() != QLocale::French) && (QLocale::system().language() != QLocale::German)) { tempHBoxLayout->addWidget(createNewKey("backslash")); } if (!m_isNumKeypad) { tempHBoxLayout->addWidget(createNewKey("Prior")); tempVBoxLayout->addLayout(tempHBoxLayout); } else { tempMiddleVLayout->addLayout(tempHBoxLayout); } tempHBoxLayout = new QHBoxLayout(); tempHBoxLayout->setSpacing(0); tempHBoxLayout->addWidget(createNewKey("Caps_Lock")); tempHBoxLayout->addWidget(createNewKey("a")); tempHBoxLayout->addWidget(createNewKey("s")); tempHBoxLayout->addWidget(createNewKey("d")); tempHBoxLayout->addWidget(createNewKey("f")); tempHBoxLayout->addWidget(createNewKey("g")); tempHBoxLayout->addWidget(createNewKey("h")); tempHBoxLayout->addWidget(createNewKey("j")); tempHBoxLayout->addWidget(createNewKey("k")); tempHBoxLayout->addWidget(createNewKey("l")); tempHBoxLayout->addWidget(createNewKey("semicolon")); tempHBoxLayout->addWidget(createNewKey("apostrophe")); if ((QLocale::system().language() == QLocale::French) || (QLocale::system().language() == QLocale::German)) { tempHBoxLayout->addWidget(createNewKey("asterisk")); } if (m_isNumKeypad) { tempMiddleVLayout->addLayout(tempHBoxLayout); tempMiddleHLayout->addLayout(tempMiddleVLayout); tempMiddleHLayout->setSpacing(0); tempMiddleHLayout->addWidget(createNewKey("Return")); tempVBoxLayout->addLayout(tempMiddleHLayout); } else { tempHBoxLayout->addWidget(createNewKey("Return")); tempHBoxLayout->addWidget(createNewKey("Next")); tempVBoxLayout->addLayout(tempHBoxLayout); delete tempMiddleHLayout; delete tempMiddleVLayout; } tempHBoxLayout = new QHBoxLayout(); tempHBoxLayout->setSpacing(0); tempHBoxLayout->addWidget(createNewKey("Shift_L")); if (QLocale::system().language() == QLocale::French) { tempHBoxLayout->addWidget(createNewKey("less")); } tempHBoxLayout->addWidget(createNewKey("z")); tempHBoxLayout->addWidget(createNewKey("x")); tempHBoxLayout->addWidget(createNewKey("c")); tempHBoxLayout->addWidget(createNewKey("v")); tempHBoxLayout->addWidget(createNewKey("b")); tempHBoxLayout->addWidget(createNewKey("n")); tempHBoxLayout->addWidget(createNewKey("m")); tempHBoxLayout->addWidget(createNewKey("comma")); tempHBoxLayout->addWidget(createNewKey("period")); tempHBoxLayout->addWidget(createNewKey("slash")); tempHBoxLayout->addWidget(createNewKey("Shift_R")); if (!m_isNumKeypad) { tempHBoxLayout->addWidget(createNewKey("Up")); tempHBoxLayout->addWidget(createNewKey("End")); } tempVBoxLayout->addLayout(tempHBoxLayout); tempHBoxLayout = new QHBoxLayout(); tempHBoxLayout->setSpacing(0); tempHBoxLayout->addWidget(createNewKey("Control_L")); tempHBoxLayout->addWidget(createNewKey("Super_L")); tempHBoxLayout->addWidget(createNewKey("Alt_L")); tempHBoxLayout->addWidget(createNewKey("space")); VirtualKeyPushButton *altR = createNewKey("Alt_R"); if (altR->getKeycode() <= 0) { tempHBoxLayout->addWidget(createNewKey("ISO_Level3_Shift")); delete altR; } else { tempHBoxLayout->addWidget(altR); } tempHBoxLayout->addWidget(createNewKey("Menu")); tempHBoxLayout->addWidget(createNewKey("Control_R")); if (!m_isNumKeypad) { tempHBoxLayout->addWidget(createNewKey("Left")); tempHBoxLayout->addWidget(createNewKey("Down")); tempHBoxLayout->addWidget(createNewKey("Right")); } tempVBoxLayout->addLayout(tempHBoxLayout); if (m_isNumKeypad) { tempVBoxLayout->setStretch(0, 1); tempVBoxLayout->setStretch(1, 2); tempVBoxLayout->setStretch(2, 1); tempVBoxLayout->setStretch(3, 1); } finalVBoxLayout->addLayout(tempVBoxLayout); if (m_isNumKeypad) { finalVBoxLayout->setStretch(0, 1); finalVBoxLayout->setStretch(1, 0); finalVBoxLayout->setStretch(2, 2); } return finalVBoxLayout; } QVBoxLayout *VirtualKeyboardMouseWidget::setupAuxKeyboardLayout() { QHBoxLayout *tempHBoxLayout = new QHBoxLayout(); QVBoxLayout *tempVBoxLayout = new QVBoxLayout(); QGridLayout *tempGridLayout = new QGridLayout(); tempHBoxLayout->setSpacing(0); tempVBoxLayout->setSpacing(0); tempGridLayout->setSpacing(0); tempHBoxLayout->addWidget(createNewKey("Print")); tempHBoxLayout->addWidget(createNewKey("Scroll_Lock")); tempHBoxLayout->addWidget(createNewKey("Pause")); tempVBoxLayout->addLayout(tempHBoxLayout); tempVBoxLayout->addSpacerItem(new QSpacerItem(20, 45, QSizePolicy::Minimum, QSizePolicy::Fixed)); tempGridLayout->addWidget(createNewKey("Insert"), 1, 1, 1, 1); tempGridLayout->addWidget(createNewKey("Home"), 1, 2, 1, 1); tempGridLayout->addWidget(createNewKey("Prior"), 1, 3, 1, 1); tempGridLayout->addWidget(createNewKey("Delete"), 2, 1, 1, 1); tempGridLayout->addWidget(createNewKey("End"), 2, 2, 1, 1); tempGridLayout->addWidget(createNewKey("Next"), 2, 3, 1, 1); tempVBoxLayout->addLayout(tempGridLayout); tempVBoxLayout->addSpacerItem(new QSpacerItem(20, 35, QSizePolicy::Minimum, QSizePolicy::Fixed)); tempGridLayout = new QGridLayout(); tempGridLayout->addWidget(createNewKey("Up"), 1, 2, 1, 1); tempGridLayout->addWidget(createNewKey("Left"), 2, 1, 1, 1); tempGridLayout->addWidget(createNewKey("Down"), 2, 2, 1, 1); tempGridLayout->addWidget(createNewKey("Right"), 2, 3, 1, 1); tempVBoxLayout->addLayout(tempGridLayout); return tempVBoxLayout; } QVBoxLayout *VirtualKeyboardMouseWidget::setupKeyboardNumPadLayout() { QHBoxLayout *tempHBoxLayout = new QHBoxLayout(); tempHBoxLayout->setSpacing(0); QVBoxLayout *tempVBoxLayout = new QVBoxLayout(); tempVBoxLayout->setSpacing(0); QGridLayout *tempGridLayout = new QGridLayout(); tempGridLayout->setSpacing(0); QVBoxLayout *finalVBoxLayout = new QVBoxLayout(); finalVBoxLayout->setSpacing(0); QPushButton *othersKeysButton = createOtherKeysMenu(); finalVBoxLayout->addWidget(noneButton); finalVBoxLayout->addWidget(othersKeysButton); finalVBoxLayout->setStretchFactor(noneButton, 1); finalVBoxLayout->setStretchFactor(othersKeysButton, 1); finalVBoxLayout->addSpacerItem(new QSpacerItem(0, 29, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding)); tempHBoxLayout = new QHBoxLayout(); tempHBoxLayout->setSpacing(0); tempHBoxLayout->addWidget(createNewKey("Num_Lock")); tempHBoxLayout->addWidget(createNewKey("KP_Divide")); tempHBoxLayout->addWidget(createNewKey("KP_Multiply")); tempHBoxLayout->addWidget(createNewKey("KP_Subtract")); tempVBoxLayout->addLayout(tempHBoxLayout); tempHBoxLayout = new QHBoxLayout(); tempHBoxLayout->setSpacing(0); tempGridLayout->addWidget(createNewKey("KP_7"), 1, 1, 1, 1); tempGridLayout->addWidget(createNewKey("KP_8"), 1, 2, 1, 1); tempGridLayout->addWidget(createNewKey("KP_9"), 1, 3, 1, 1); tempGridLayout->addWidget(createNewKey("KP_4"), 2, 1, 1, 1); tempGridLayout->addWidget(createNewKey("KP_5"), 2, 2, 1, 1); tempGridLayout->addWidget(createNewKey("KP_6"), 2, 3, 1, 1); tempHBoxLayout->addLayout(tempGridLayout); tempHBoxLayout->addWidget(createNewKey("KP_Add")); tempVBoxLayout->addLayout(tempHBoxLayout); tempHBoxLayout = new QHBoxLayout(); tempHBoxLayout->setSpacing(0); tempGridLayout = new QGridLayout(); tempGridLayout->setSpacing(0); tempGridLayout->addWidget(createNewKey("KP_1"), 1, 1, 1, 1); tempGridLayout->addWidget(createNewKey("KP_2"), 1, 2, 1, 1); tempGridLayout->addWidget(createNewKey("KP_3"), 1, 3, 1, 1); tempGridLayout->addWidget(createNewKey("KP_0"), 2, 1, 1, 2); tempGridLayout->addWidget(createNewKey("KP_Delete"), 2, 3, 1, 1); tempHBoxLayout->addLayout(tempGridLayout); tempHBoxLayout->addWidget(createNewKey("KP_Enter")); tempVBoxLayout->addLayout(tempHBoxLayout); finalVBoxLayout->addLayout(tempVBoxLayout); finalVBoxLayout->setStretchFactor(tempVBoxLayout, 8); return finalVBoxLayout; } void VirtualKeyboardMouseWidget::setupMouseControlLayout() { QHBoxLayout *tempHBoxLayout = new QHBoxLayout(); QVBoxLayout *tempVBoxLayout = new QVBoxLayout(); QGridLayout *tempGridLayout = new QGridLayout(); QVBoxLayout *finalVBoxLayout = new QVBoxLayout(mouseTab); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); VirtualMousePushButton *pushButton = new VirtualMousePushButton(tr("Left", "Mouse"), JoyButtonSlot::MouseLeft, JoyButtonSlot::JoyMouseMovement, this); pushButton->setSizePolicy(sizePolicy); pushButton->setMinimumHeight(50); tempVBoxLayout->addSpacerItem(new QSpacerItem(20, 50, QSizePolicy::Minimum, QSizePolicy::Expanding)); tempVBoxLayout->addWidget(pushButton); tempVBoxLayout->addSpacerItem(new QSpacerItem(20, 50, QSizePolicy::Minimum, QSizePolicy::Expanding)); tempHBoxLayout->addLayout(tempVBoxLayout); tempHBoxLayout->addSpacerItem(new QSpacerItem(10, 20, QSizePolicy::Fixed)); tempVBoxLayout = new QVBoxLayout(); pushButton = new VirtualMousePushButton(tr("Up", "Mouse"), JoyButtonSlot::MouseUp, JoyButtonSlot::JoyMouseMovement, this); pushButton->setSizePolicy(sizePolicy); pushButton->setMinimumHeight(50); tempVBoxLayout->addWidget(pushButton); tempVBoxLayout->addSpacerItem(new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed)); QHBoxLayout *tempInnerHBoxLayout = new QHBoxLayout(); pushButton = new VirtualMousePushButton(tr("Left Button", "Mouse"), 1, JoyButtonSlot::JoyMouseButton, this); pushButton->setSizePolicy(sizePolicy); tempInnerHBoxLayout->addWidget(pushButton); pushButton = new VirtualMousePushButton(tr("Middle Button", "Mouse"), 2, JoyButtonSlot::JoyMouseButton, this); pushButton->setSizePolicy(sizePolicy); tempInnerHBoxLayout->addWidget(pushButton); pushButton = new VirtualMousePushButton(tr("Right Button", "Mouse"), 3, JoyButtonSlot::JoyMouseButton, this); pushButton->setSizePolicy(sizePolicy); tempInnerHBoxLayout->addWidget(pushButton); tempVBoxLayout->addLayout(tempInnerHBoxLayout); tempVBoxLayout->addSpacerItem(new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed)); pushButton = new VirtualMousePushButton(tr("Wheel Up", "Mouse"), 4, JoyButtonSlot::JoyMouseButton, this); pushButton->setSizePolicy(sizePolicy); pushButton->setMinimumHeight(30); tempGridLayout->addWidget(pushButton, 1, 2, 1, 1); pushButton = new VirtualMousePushButton(tr("Wheel Left", "Mouse"), 6, JoyButtonSlot::JoyMouseButton, this); pushButton->setSizePolicy(sizePolicy); pushButton->setMinimumHeight(30); tempGridLayout->addWidget(pushButton, 2, 1, 1, 1); pushButton = new VirtualMousePushButton(tr("Wheel Right", "Mouse"), 7, JoyButtonSlot::JoyMouseButton, this); pushButton->setSizePolicy(sizePolicy); pushButton->setMinimumHeight(30); tempGridLayout->addWidget(pushButton, 2, 3, 1, 1); pushButton = new VirtualMousePushButton(tr("Wheel Down", "Mouse"), 5, JoyButtonSlot::JoyMouseButton, this); pushButton->setSizePolicy(sizePolicy); pushButton->setMinimumHeight(30); tempGridLayout->addWidget(pushButton, 3, 2, 1, 1); tempVBoxLayout->addLayout(tempGridLayout); tempVBoxLayout->addSpacerItem(new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Fixed)); pushButton = new VirtualMousePushButton(tr("Down", "Mouse"), JoyButtonSlot::MouseDown, JoyButtonSlot::JoyMouseMovement, this); pushButton->setSizePolicy(sizePolicy); pushButton->setMinimumHeight(50); tempVBoxLayout->addWidget(pushButton); tempVBoxLayout->setStretch(0, 1); tempVBoxLayout->setStretch(2, 1); tempVBoxLayout->setStretch(4, 3); tempVBoxLayout->setStretch(6, 1); tempHBoxLayout->addLayout(tempVBoxLayout); tempHBoxLayout->addSpacerItem(new QSpacerItem(10, 20, QSizePolicy::Fixed)); tempVBoxLayout = new QVBoxLayout(); tempVBoxLayout->addSpacerItem(new QSpacerItem(20, 50, QSizePolicy::Minimum, QSizePolicy::Expanding)); pushButton = new VirtualMousePushButton(tr("Right", "Mouse"), JoyButtonSlot::MouseRight, JoyButtonSlot::JoyMouseMovement, this); pushButton->setSizePolicy(sizePolicy); pushButton->setMinimumHeight(50); tempVBoxLayout->addWidget(pushButton); tempVBoxLayout->addSpacerItem(new QSpacerItem(20, 50, QSizePolicy::Minimum, QSizePolicy::Expanding)); tempHBoxLayout->addLayout(tempVBoxLayout); tempHBoxLayout->addSpacerItem(new QSpacerItem(10, 20, QSizePolicy::Fixed)); tempVBoxLayout = new QVBoxLayout(); tempVBoxLayout->setSpacing(20); #ifdef Q_OS_WIN pushButton = new VirtualMousePushButton(tr("Button 4", "Mouse"), 8, JoyButtonSlot::JoyMouseButton, this); #else pushButton = new VirtualMousePushButton(tr("Mouse 8", "Mouse"), 8, JoyButtonSlot::JoyMouseButton, this); #endif pushButton->setMinimumHeight(40); tempVBoxLayout->addWidget(pushButton); #ifdef Q_OS_WIN pushButton = new VirtualMousePushButton(tr("Button 5", "Mouse"), 9, JoyButtonSlot::JoyMouseButton, this); #else pushButton = new VirtualMousePushButton(tr("Mouse 9", "Mouse"), 9, JoyButtonSlot::JoyMouseButton, this); #endif pushButton->setMinimumHeight(40); tempVBoxLayout->addWidget(pushButton); tempVBoxLayout->addSpacerItem(new QSpacerItem(20, 50, QSizePolicy::Minimum, QSizePolicy::Expanding)); tempHBoxLayout->addLayout(tempVBoxLayout); tempHBoxLayout->addSpacerItem(new QSpacerItem(10, 20, QSizePolicy::Fixed)); tempVBoxLayout = new QVBoxLayout(); tempVBoxLayout->setSpacing(20); tempVBoxLayout->addSpacerItem(new QSpacerItem(20, 10, QSizePolicy::Minimum, QSizePolicy::Expanding)); mouseSettingsPushButton = new QPushButton(tr("Mouse Settings"), this); mouseSettingsPushButton->setIcon(PadderCommon::loadIcon("input-mouse", ":/images/actions/edit_select.png")); tempVBoxLayout->addWidget(mouseSettingsPushButton); mouseSettingsPushButton->setEnabled(false); tempHBoxLayout->addLayout(tempVBoxLayout); finalVBoxLayout->addLayout(tempHBoxLayout); } VirtualKeyPushButton *VirtualKeyboardMouseWidget::createNewKey(QString xcodestring) { int width = 32; int height = 32; QFont font1; font1.setPointSize(8); font1.setBold(true); VirtualKeyPushButton *pushButton = new VirtualKeyPushButton(xcodestring, this); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); pushButton->setSizePolicy(sizePolicy); if (xcodestring == "space") { width = 131; } else if (xcodestring == "Tab") { width = 43; } else if (xcodestring == "Shift_L") { width = 77; } else if (xcodestring == "Shift_R") { if (!m_isNumKeypad) width = 59; else width = 95; } else if (xcodestring == "Caps_Lock") { width = 59; } else if (xcodestring == "Return") { width = 64; if (m_isNumKeypad) height = 64; pushButton->setMaximumWidth(100); } else if (xcodestring == "BackSpace") { width = 68; } else if (topRowKeys.contains(xcodestring)) { width = 30; height = 32; pushButton->setMaximumSize(100, 100); } else if ((xcodestring == "Print") || (xcodestring == "Scroll_Lock") || (xcodestring == "Pause")) { width = 32; height = 32; pushButton->setMaximumSize(100, 100); font1.setPointSize(6); } else if ((xcodestring == "KP_Add") || (xcodestring == "KP_Enter")) { height = 56; width = 32; font1.setPointSize(5); } else if (xcodestring == "Num_Lock") { width = 32; height = 32; font1.setPointSize(5); } else if (xcodestring.startsWith("KP_")) { width = 32; } else if (xcodestring == "backslash") { if (m_isNumKeypad) width = 32; else width = 43; } else if ((xcodestring == "Down") || (xcodestring == "Left") || (xcodestring == "Right")) { if (!m_isNumKeypad) { QSizePolicy sizePolicy2(QSizePolicy::Fixed, QSizePolicy::Preferred); pushButton->setSizePolicy(sizePolicy2); pushButton->setFixedWidth(58); } } else if ((xcodestring == "Control_L") || (xcodestring == "Super_L") || (xcodestring == "Alt_L") || (xcodestring == "Alt_R") || (xcodestring == "ISO_Level3_Shift") || (xcodestring == "Menu") || (xcodestring == "Control_R")) { if (!m_isNumKeypad) width = 32; else width = 41; } else if ((xcodestring.startsWith("F") && (xcodestring.length() > 1)) || (xcodestring == "Print") || (xcodestring == "Escape") || (xcodestring == "Pause") || (xcodestring == "Delete")) { if (!m_isNumKeypad) { QSizePolicy sizePolicy2(QSizePolicy::Fixed, QSizePolicy::Fixed); pushButton->setSizePolicy(sizePolicy2); width = 32; height = 25; font1.setPointSize(5); } } pushButton->setObjectName(xcodestring); pushButton->setMinimumSize(width, height); pushButton->setFont(font1); return pushButton; } QPushButton *VirtualKeyboardMouseWidget::createNoneKey() { QPushButton *pushButton = new QPushButton(tr("NONE"), this); pushButton->setMinimumSize(0, 25); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); pushButton->setSizePolicy(sizePolicy); QFont font1; font1.setBold(true); pushButton->setFont(font1); return pushButton; } void VirtualKeyboardMouseWidget::processSingleKeyboardSelection(int keycode, int alias) { if ((currentQuickDialog == nullptr) && !withoutQuickSetDialog) { currentQuickDialog = new QuickSetDialog(joystick, helper, "setAssignedSlot", keycode, alias, 0, JoyButtonSlot::JoyKeyboard, true, true, this); currentQuickDialog->show(); connect(currentQuickDialog, &QuickSetDialog::finished, this, &VirtualKeyboardMouseWidget::nullifyDialogPointer); } else if (withoutQuickSetDialog) { ButtonEditDialog::getInstance()->invokeMethodLastBtn(lastPressedBtn, helper, "setAssignedSlot", keycode, alias, 0, JoyButtonSlot::JoyKeyboard, true, true, Qt::QueuedConnection, Qt::QueuedConnection, Qt::QueuedConnection); ButtonEditDialog::getInstance()->refreshForLastBtn(); } } void VirtualKeyboardMouseWidget::processAdvancedKeyboardSelection(int keycode, int alias) { emit selectionMade(keycode, alias); } void VirtualKeyboardMouseWidget::processSingleMouseSelection(JoyButtonSlot *tempslot) { if ((currentQuickDialog == nullptr) && !withoutQuickSetDialog) { currentQuickDialog = new QuickSetDialog(joystick, helper, "setAssignedSlot", tempslot->getSlotCode(), -1, -1, tempslot->getSlotMode(), true, true, this); currentQuickDialog->show(); connect(currentQuickDialog, &QuickSetDialog::finished, this, &VirtualKeyboardMouseWidget::nullifyDialogPointer); } else if (withoutQuickSetDialog) { ButtonEditDialog::getInstance()->invokeMethodLastBtn( lastPressedBtn, helper, "setAssignedSlot", tempslot->getSlotCode(), -1, -1, tempslot->getSlotMode(), true, true, Qt::QueuedConnection, Qt::QueuedConnection, Qt::QueuedConnection); ButtonEditDialog::getInstance()->refreshForLastBtn(); } } void VirtualKeyboardMouseWidget::processAdvancedMouseSelection(JoyButtonSlot *tempslot) { emit selectionMade(tempslot); } void VirtualKeyboardMouseWidget::populateTopRowKeys() { if (topRowKeys.isEmpty()) { topRowKeys.insert("Escape", "Escape"); topRowKeys.insert("F1", "F1"); topRowKeys.insert("F2", "F2"); topRowKeys.insert("F3", "F3"); topRowKeys.insert("F4", "F4"); topRowKeys.insert("F5", "F5"); topRowKeys.insert("F6", "F6"); topRowKeys.insert("F7", "F7"); topRowKeys.insert("F8", "F8"); topRowKeys.insert("F9", "F9"); topRowKeys.insert("F10", "F10"); topRowKeys.insert("F11", "F11"); topRowKeys.insert("F12", "F12"); } } void VirtualKeyboardMouseWidget::addFButtonToOthers(int qt_keycode, QString keycode_text) { if (keysymToKeyString(AntKeyMapper::getInstance()->returnVirtualKey(qt_keycode)) != tr("[NO KEY]")) { QAction *tempAction = new QAction(keycode_text, otherKeysMenu); tempAction->setData(AntKeyMapper::getInstance()->returnVirtualKey(qt_keycode)); otherKeysMenu->addAction(tempAction); } } void VirtualKeyboardMouseWidget::establishVirtualKeyboardSingleSignalConnections() { QList newlist = keyboardTab->findChildren(); QListIterator iter(newlist); while (iter.hasNext()) { VirtualKeyPushButton *keybutton = iter.next(); disconnect(keybutton, &VirtualKeyPushButton::keycodeObtained, nullptr, nullptr); connect(keybutton, &VirtualKeyPushButton::keycodeObtained, this, &VirtualKeyboardMouseWidget::processSingleKeyboardSelection); } QListIterator iterActions(otherKeysMenu->actions()); while (iterActions.hasNext()) { QAction *temp = iterActions.next(); disconnect(temp, &QAction::triggered, nullptr, nullptr); connect(temp, &QAction::triggered, this, [this, temp](bool checked) { otherKeysActionSingle(temp, checked); }); } disconnect(noneButton, &QPushButton::clicked, nullptr, nullptr); connect(noneButton, &QPushButton::clicked, this, &VirtualKeyboardMouseWidget::clearButtonSlotsFinish); } void VirtualKeyboardMouseWidget::establishVirtualKeyboardAdvancedSignalConnections() { QList newlist = keyboardTab->findChildren(); QListIterator iter(newlist); while (iter.hasNext()) { VirtualKeyPushButton *keybutton = iter.next(); disconnect(keybutton, &VirtualKeyPushButton::keycodeObtained, nullptr, nullptr); connect(keybutton, &VirtualKeyPushButton::keycodeObtained, this, &VirtualKeyboardMouseWidget::processAdvancedKeyboardSelection); } QListIterator iterActions(otherKeysMenu->actions()); while (iterActions.hasNext()) { QAction *temp = iterActions.next(); disconnect(temp, &QAction::triggered, nullptr, nullptr); connect(temp, &QAction::triggered, this, [this, temp](bool checked) { otherKeysActionAdvanced(temp, checked); }); } disconnect(noneButton, &QPushButton::clicked, nullptr, nullptr); connect(noneButton, &QPushButton::clicked, this, &VirtualKeyboardMouseWidget::clearButtonSlots); } void VirtualKeyboardMouseWidget::establishVirtualMouseSignalConnections() { QList newlist = mouseTab->findChildren(); QListIterator iter(newlist); while (iter.hasNext()) { VirtualMousePushButton *mousebutton = iter.next(); disconnect(mousebutton, &VirtualMousePushButton::mouseSlotCreated, nullptr, nullptr); connect(mousebutton, &VirtualMousePushButton::mouseSlotCreated, this, &VirtualKeyboardMouseWidget::processSingleMouseSelection); } } void VirtualKeyboardMouseWidget::establishVirtualMouseAdvancedSignalConnections() { QList newlist = mouseTab->findChildren(); QListIterator iter(newlist); while (iter.hasNext()) { VirtualMousePushButton *mousebutton = iter.next(); disconnect(mousebutton, &VirtualMousePushButton::mouseSlotCreated, nullptr, nullptr); connect(mousebutton, &VirtualMousePushButton::mouseSlotCreated, this, &VirtualKeyboardMouseWidget::processAdvancedMouseSelection); } } void VirtualKeyboardMouseWidget::clearButtonSlots() { if (ButtonEditDialog::getInstance() != nullptr) { if (ButtonEditDialog::getInstance()->getLastJoyButton() != nullptr) QMetaObject::invokeMethod(ButtonEditDialog::getInstance()->getLastJoyButton(), "clearSlotsEventReset", Qt::BlockingQueuedConnection); emit selectionCleared(); lastPressedBtn->buildActiveZoneSummaryString(); } else { QMessageBox::information(this, tr("Last button"), tr("Slots for button couldn't be cleared, because there was not any set button from " "keyboard for gamepad. Map at least one button from keyboard to gamepad")); } } void VirtualKeyboardMouseWidget::clearButtonSlotsFinish() { if (ButtonEditDialog::getInstance() != nullptr) { if (ButtonEditDialog::getInstance()->getLastJoyButton() != nullptr) QMetaObject::invokeMethod(ButtonEditDialog::getInstance()->getLastJoyButton(), "clearSlotsEventReset", Qt::BlockingQueuedConnection); emit selectionFinished(); lastPressedBtn->buildActiveZoneSummaryString(); } else { QMessageBox::information(this, tr("Last button"), tr("Slots for button couldn't be cleared, because there was not any set button from " "keyboard for gamepad. Map at least one button from keyboard to gamepad")); } } bool VirtualKeyboardMouseWidget::isKeyboardTabVisible() { return this->keyboardTab->isVisible(); } void VirtualKeyboardMouseWidget::openMouseSettingsDialog() { mouseSettingsPushButton->setEnabled(false); // TODO instead of buttons, get pointer to static getInstance from ButtonEditDialog for last pressed button, and then // getting button from public method if (ButtonEditDialog::getInstance() != nullptr) { if (ButtonEditDialog::getInstance()->getLastJoyButton() != nullptr) { MouseButtonSettingsDialog *dialog = new MouseButtonSettingsDialog(ButtonEditDialog::getInstance()->getLastJoyButton(), this); dialog->show(); QDialog *parent = qobject_cast(this->parentWidget()); // static_cast connect(parent, &QDialog::finished, dialog, &MouseButtonSettingsDialog::close); connect(dialog, &MouseButtonSettingsDialog::finished, this, &VirtualKeyboardMouseWidget::enableMouseSettingButton); } else { QMessageBox::information(this, QObject::tr("Last button"), QObject::tr("There isn't a last button pressed from gamepad in data. Did you set at " "least one button from gamepad for keyboard?")); } } } void VirtualKeyboardMouseWidget::enableMouseSettingButton() { mouseSettingsPushButton->setEnabled(true); } void VirtualKeyboardMouseWidget::disableMouseSettingButton() { mouseSettingsPushButton->setEnabled(false); } void VirtualKeyboardMouseWidget::resizeEvent(QResizeEvent *event) { QTabWidget::resizeEvent(event); setButtonFontSizes(); } // Dynamically change font size of list of push button according to the // size of the buttons. void VirtualKeyboardMouseWidget::setButtonFontSizes() { QList buttonList = this->findChildren(); QListIterator iter(buttonList); while (iter.hasNext()) { VirtualKeyPushButton *temp = iter.next(); QFont tempFont(temp->font()); tempFont.setPointSize(temp->calculateFontSize()); temp->setFont(tempFont); } } QPushButton *VirtualKeyboardMouseWidget::createOtherKeysMenu() { QPushButton *otherKeysPushbutton = new QPushButton(tr("Others"), this); otherKeysPushbutton->setMinimumSize(0, 25); QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); otherKeysPushbutton->setSizePolicy(sizePolicy); QFont font1; font1.setBold(true); otherKeysPushbutton->setFont(font1); otherKeysMenu = new QMenu(this); QAction *tempAction = nullptr; int temp = 0; #ifdef Q_OS_WIN tempAction = new QAction(tr("Applications"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Menu); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); #endif tempAction = new QAction(tr("Browser Back"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Back); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Browser Favorites"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Favorites); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Browser Forward"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Forward); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Browser Home"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_HomePage); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Browser Refresh"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Refresh); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Browser Search"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Search); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Browser Stop"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Stop); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Calc"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Launch1); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Email"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_LaunchMail); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); addFButtonToOthers(Qt::Key_F13, tr("F13")); addFButtonToOthers(Qt::Key_F14, tr("F14")); addFButtonToOthers(Qt::Key_F15, tr("F15")); addFButtonToOthers(Qt::Key_F16, tr("F16")); addFButtonToOthers(Qt::Key_F17, tr("F17")); addFButtonToOthers(Qt::Key_F18, tr("F18")); addFButtonToOthers(Qt::Key_F19, tr("F19")); addFButtonToOthers(Qt::Key_F20, tr("F20")); addFButtonToOthers(Qt::Key_F21, tr("F21")); addFButtonToOthers(Qt::Key_F22, tr("F22")); addFButtonToOthers(Qt::Key_F23, tr("F23")); addFButtonToOthers(Qt::Key_F24, tr("F24")); tempAction = new QAction(tr("Media"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_LaunchMedia); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Media Next"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_MediaNext); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Media Play"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_MediaPlay); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Media Previous"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_MediaPrevious); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Media Stop"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_MediaStop); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Search"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_Search); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Volume Down"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_VolumeDown); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Volume Mute"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_VolumeMute); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); tempAction = new QAction(tr("Volume Up"), otherKeysMenu); temp = AntKeyMapper::getInstance()->returnVirtualKey(Qt::Key_VolumeUp); tempAction->setData(temp); otherKeysMenu->addAction(tempAction); otherKeysPushbutton->setMenu(otherKeysMenu); return otherKeysPushbutton; } void VirtualKeyboardMouseWidget::otherKeysActionSingle(QAction *tempAction, bool triggered) { Q_UNUSED(triggered); int virtualkey = tempAction->data().toInt(); processSingleKeyboardSelection(virtualkey, AntKeyMapper::getInstance()->returnQtKey(virtualkey)); } void VirtualKeyboardMouseWidget::otherKeysActionAdvanced(QAction *tempAction, bool triggered) { Q_UNUSED(triggered); int virtualkey = tempAction->data().toInt(); processAdvancedKeyboardSelection(virtualkey, AntKeyMapper::getInstance()->returnQtKey(virtualkey)); } void VirtualKeyboardMouseWidget::nullifyDialogPointer() { if (currentQuickDialog != nullptr) { ButtonEditDialog::getInstance()->setUpLastJoyButton(currentQuickDialog->getLastPressedButton()); ButtonEditDialog::getInstance()->refreshForLastBtn(); enableMouseSettingButton(); currentQuickDialog = nullptr; emit buttonDialogClosed(); } } InputDevice *VirtualKeyboardMouseWidget::getJoystick() const { return joystick; } ButtonEditDialogHelper *VirtualKeyboardMouseWidget::getHelper() const { return helper; } QWidget *VirtualKeyboardMouseWidget::getKeyboardTab() const { return keyboardTab; } QWidget *VirtualKeyboardMouseWidget::getMouseTab() const { return mouseTab; } QPushButton *VirtualKeyboardMouseWidget::getNoneButton() const { return noneButton; } QPushButton *VirtualKeyboardMouseWidget::getMouseSettingsPushButton() const { return mouseSettingsPushButton; } QMenu *VirtualKeyboardMouseWidget::getOtherKeysMenu() const { return otherKeysMenu; } QuickSetDialog *VirtualKeyboardMouseWidget::getCurrentQuickDialog() const { return currentQuickDialog; } AntiMicroX-antimicrox-b300273/src/keyboard/virtualkeyboardmousewidget.h000066400000000000000000000102001471077622000263670ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef VIRTUALKEYBOARDMOUSEWIDGET_H #define VIRTUALKEYBOARDMOUSEWIDGET_H #include #include class JoyButton; class JoyButtonSlot; class VirtualKeyPushButton; class QVBoxLayout; class QPushButton; class QWidget; class InputDevice; class QuickSetDialog; class ButtonEditDialogHelper; /** * @brief Widget visualizing possible keyboard and mouse assignments. * * It is part of buttoneditdialog. */ class VirtualKeyboardMouseWidget : public QTabWidget { Q_OBJECT public: explicit VirtualKeyboardMouseWidget(InputDevice *joystick, ButtonEditDialogHelper *helper, bool isNumKeypad, QuickSetDialog *quickSetDialog = nullptr, JoyButton *button = nullptr, QWidget *parent = nullptr); explicit VirtualKeyboardMouseWidget(bool isNumKeypad, QWidget *parent = nullptr); bool isKeyboardTabVisible(); bool is_numlock_activated(); // RealSystemInfo class bool isLaptop(); // RealSystemInfo class InputDevice *getJoystick() const; ButtonEditDialogHelper *getHelper() const; QWidget *getKeyboardTab() const; QWidget *getMouseTab() const; QPushButton *getNoneButton() const; QPushButton *getMouseSettingsPushButton() const; QMenu *getOtherKeysMenu() const; QuickSetDialog *getCurrentQuickDialog() const; static QHash topRowKeys; protected: void setupVirtualKeyboardLayout(); QVBoxLayout *setupMainKeyboardLayout(); QVBoxLayout *setupAuxKeyboardLayout(); QVBoxLayout *setupKeyboardNumPadLayout(); void setupMouseControlLayout(); VirtualKeyPushButton *createNewKey(QString xcodestring); QPushButton *createNoneKey(); void populateTopRowKeys(); void addFButtonToOthers(int qt_keycode, QString keycode_text); QPushButton *createOtherKeysMenu(); virtual void resizeEvent(QResizeEvent *event); signals: void selectionFinished(); void selectionCleared(); void selectionMade(int keycode, int alias); void selectionMade(JoyButtonSlot *slot); void buttonDialogClosed(); public slots: void establishVirtualKeyboardSingleSignalConnections(); void establishVirtualMouseSignalConnections(); void establishVirtualKeyboardAdvancedSignalConnections(); void establishVirtualMouseAdvancedSignalConnections(); void enableMouseSettingButton(); void disableMouseSettingButton(); private slots: void processSingleKeyboardSelection(int keycode, int alias); void processAdvancedKeyboardSelection(int keycode, int alias); void processSingleMouseSelection(JoyButtonSlot *tempslot); void processAdvancedMouseSelection(JoyButtonSlot *tempslot); void clearButtonSlots(); void clearButtonSlotsFinish(); void openMouseSettingsDialog(); void setButtonFontSizes(); void otherKeysActionSingle(QAction *action, bool triggered); void otherKeysActionAdvanced(QAction *action, bool triggered); void nullifyDialogPointer(); private: bool withoutQuickSetDialog; bool m_isNumKeypad; InputDevice *joystick; JoyButton *lastPressedBtn; ButtonEditDialogHelper *helper; QWidget *keyboardTab; QWidget *mouseTab; QPushButton *noneButton; QPushButton *mouseSettingsPushButton; QMenu *otherKeysMenu; QuickSetDialog *currentQuickDialog; }; #endif // VIRTUALKEYBOARDMOUSEWIDGET_H AntiMicroX-antimicrox-b300273/src/keyboard/virtualkeypushbutton.cpp000066400000000000000000000170211471077622000256010ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "virtualkeypushbutton.h" #include "antkeymapper.h" #include "event.h" #include "eventhandlerfactory.h" #include #include #include #include QHash VirtualKeyPushButton::knownAliases = QHash(); VirtualKeyPushButton::VirtualKeyPushButton(QString xcodestring, QWidget *parent) : QPushButton(parent) { populateKnownAliases(); // qDebug() << "Question: " << X11KeySymToKeycode("KP_7"); // qDebug() << "Question: " << X11KeySymToKeycode(79); this->keycode = 0; this->qkeyalias = 0; this->xcodestring = ""; this->displayString = ""; this->currentlyActive = false; this->onCurrentButton = false; int temp = 0; if (!xcodestring.isEmpty()) { temp = X11KeySymToKeycode(xcodestring); #ifdef Q_OS_UNIX BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); if (handler->getIdentifier() == "xtest") { temp = X11KeyCodeToX11KeySym(temp); } #endif } if (temp > 0) { #ifdef Q_OS_WIN // static QtWinKeyMapper nativeWinKeyMapper; BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); BACKEND_ELSE_IF(handler->getIdentifier() == "sendinput") { this->keycode = temp; this->qkeyalias = AntKeyMapper::getInstance()->returnQtKey(this->keycode); } // Special exception for Numpad Enter on Windows. if (xcodestring == "KP_Enter") { this->qkeyalias = Qt::Key_Enter; } #else this->keycode = temp; // this->keycode = X11KeyCodeToX11KeySym(temp); this->qkeyalias = AntKeyMapper::getInstance()->returnQtKey(this->keycode); // this->keycode = temp; #endif this->xcodestring = xcodestring; this->displayString = setDisplayString(xcodestring); } qDebug() << "qkeyalias after returnQtKey: " << this->qkeyalias; qDebug() << "keycode: " << this->keycode; qDebug() << "xcodestring: " << this->xcodestring; qDebug() << "displayString: " << this->displayString; this->setText(this->displayString.replace("&", "&&")); connect(this, &VirtualKeyPushButton::clicked, this, &VirtualKeyPushButton::processSingleSelection); } void VirtualKeyPushButton::processSingleSelection() { emit keycodeObtained(keycode, qkeyalias); } QString VirtualKeyPushButton::setDisplayString(QString xcodestring) { QString temp = QString(); if (knownAliases.contains(xcodestring)) { temp = knownAliases.value(xcodestring); } else { temp = keycodeToKeyString(X11KeySymToKeycode(xcodestring)); } if (temp.isEmpty() && !xcodestring.isEmpty()) { temp = xcodestring; } return temp.toUpper(); } // Define display strings that will be used for various keys on the // virtual keyboard. void VirtualKeyPushButton::populateKnownAliases() { if (knownAliases.isEmpty()) { knownAliases.insert("space", tr("Space")); knownAliases.insert("Tab", tr("Tab")); knownAliases.insert("Shift_L", tr("Shift (L)")); knownAliases.insert("Shift_R", tr("Shift (R)")); knownAliases.insert("Control_L", tr("Ctrl (L)")); knownAliases.insert("Control_R", tr("Ctrl (R)")); knownAliases.insert("Alt_L", tr("Alt (L)")); knownAliases.insert("Alt_R", tr("Alt (R)")); knownAliases.insert("ISO_Level3_Shift", tr("Alt Gr")); knownAliases.insert("Multi_key", tr("Alt (R)")); knownAliases.insert("grave", tr("`")); knownAliases.insert("asciitilde", tr("~")); knownAliases.insert("minus", tr("-")); knownAliases.insert("equal", tr("=")); knownAliases.insert("bracketleft", tr("[")); knownAliases.insert("bracketright", tr("]")); knownAliases.insert("backslash", tr("\\")); knownAliases.insert("Caps_Lock", tr("Caps")); knownAliases.insert("semicolon", tr(";")); knownAliases.insert("apostrophe", tr("'")); knownAliases.insert("comma", tr(",")); knownAliases.insert("period", tr(".")); knownAliases.insert("slash", tr("/")); knownAliases.insert("Escape", tr("ESC")); knownAliases.insert("Print", tr("PRTSC")); knownAliases.insert("Scroll_Lock", tr("SCLK")); knownAliases.insert("Insert", tr("INS")); knownAliases.insert("Prior", tr("PGUP")); knownAliases.insert("Delete", tr("DEL")); knownAliases.insert("Next", tr("PGDN")); knownAliases.insert("KP_1", tr("1")); knownAliases.insert("KP_2", tr("2")); knownAliases.insert("KP_3", tr("3")); knownAliases.insert("KP_4", tr("4")); knownAliases.insert("KP_5", tr("5")); knownAliases.insert("KP_6", tr("6")); knownAliases.insert("KP_7", tr("7")); knownAliases.insert("KP_8", tr("8")); knownAliases.insert("KP_9", tr("9")); knownAliases.insert("KP_0", tr("0")); knownAliases.insert("Num_Lock", tr("NUM\nLK")); knownAliases.insert("KP_Divide", tr("/")); knownAliases.insert("KP_Multiply", tr("*")); knownAliases.insert("KP_Subtract", tr("-")); knownAliases.insert("KP_Add", tr("+")); knownAliases.insert("KP_Enter", tr("Enter")); knownAliases.insert("KP_Decimal", tr(".")); knownAliases.insert("KP_Delete", tr("Del")); knownAliases.insert("asterisk", tr("*")); knownAliases.insert("less", tr("<")); knownAliases.insert("colon", tr(":")); knownAliases.insert("Super_L", tr("Super (L)")); knownAliases.insert("Menu", tr("Menu")); knownAliases.insert("Up", tr("Up")); knownAliases.insert("Down", tr("Down")); knownAliases.insert("Left", tr("Left")); knownAliases.insert("Right", tr("Right")); } } int VirtualKeyPushButton::calculateFontSize() { QFont tempScaledFont(this->font()); tempScaledFont.setPointSize(10); QFontMetrics fm(tempScaledFont); int less_width = this->width() - 4; while ((less_width < fm.boundingRect(this->rect(), Qt::AlignCenter, this->text()).width()) && (tempScaledFont.pointSize() > 5)) { tempScaledFont.setPointSize(tempScaledFont.pointSize() - 1); fm = QFontMetrics(tempScaledFont); } return tempScaledFont.pointSize(); } int VirtualKeyPushButton::getKeycode() const { return keycode; } int VirtualKeyPushButton::getQkeyalias() const { return qkeyalias; } QString VirtualKeyPushButton::getXcodestring() const { return xcodestring; } QString VirtualKeyPushButton::getDisplayString() const { return displayString; } bool VirtualKeyPushButton::getCurrentlyActive() const { return currentlyActive; } bool VirtualKeyPushButton::getOnCurrentButton() const { return onCurrentButton; } AntiMicroX-antimicrox-b300273/src/keyboard/virtualkeypushbutton.h000066400000000000000000000034601471077622000252500ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef VIRTUALKEYPUSHBUTTON_H #define VIRTUALKEYPUSHBUTTON_H #include /** * @brief PushButton representing keyboard button on VirtualKeyboardMouseWidget * */ class VirtualKeyPushButton : public QPushButton { Q_OBJECT public: explicit VirtualKeyPushButton(QString xcodestring, QWidget *parent = nullptr); int calculateFontSize(); QString getXcodestring() const; QString getDisplayString() const; int getKeycode() const; int getQkeyalias() const; bool getCurrentlyActive() const; bool getOnCurrentButton() const; static QHash knownAliases; protected: QString setDisplayString(QString xcodestring); void populateKnownAliases(); signals: void keycodeObtained(int code, int alias); private slots: void processSingleSelection(); private: int keycode; int qkeyalias; QString xcodestring; QString displayString; bool currentlyActive; bool onCurrentButton; }; #endif // VIRTUALKEYPUSHBUTTON_H AntiMicroX-antimicrox-b300273/src/keyboard/virtualmousepushbutton.cpp000066400000000000000000000044451471077622000261470ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "virtualmousepushbutton.h" #include VirtualMousePushButton::VirtualMousePushButton(QString displayText, int code, JoyButtonSlot::JoySlotInputAction mode, QWidget *parent) : QPushButton(parent) { if ((mode == JoyButtonSlot::JoyMouseButton) || (mode == JoyButtonSlot::JoyMouseMovement)) { this->setText(displayText); if (mode == JoyButtonSlot::JoyMouseMovement) { switch (code) { case JoyButtonSlot::MouseUp: case JoyButtonSlot::MouseDown: case JoyButtonSlot::MouseLeft: case JoyButtonSlot::MouseRight: { this->code = code; break; } default: { this->code = 0; break; } } } else { this->code = code; } this->mode = mode; } else { this->setText(tr("INVALID")); this->code = 0; this->mode = JoyButtonSlot::JoyMouseButton; } connect(this, &VirtualMousePushButton::clicked, this, &VirtualMousePushButton::createTempSlot); } int VirtualMousePushButton::getMouseCode() const { return code; } JoyButtonSlot::JoySlotInputAction VirtualMousePushButton::getMouseMode() const { return mode; } void VirtualMousePushButton::createTempSlot() { JoyButtonSlot *tempslot = new JoyButtonSlot(this->code, this->mode, this); emit mouseSlotCreated(tempslot); } AntiMicroX-antimicrox-b300273/src/keyboard/virtualmousepushbutton.h000066400000000000000000000030571471077622000256120ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef VIRTUALMOUSEPUSHBUTTON_H #define VIRTUALMOUSEPUSHBUTTON_H #include #include /** * @brief PushButton representing mouse action in VirtualKeyboardMouseWidget * */ class VirtualMousePushButton : public QPushButton { Q_OBJECT public: explicit VirtualMousePushButton(QString displayText, int code, JoyButtonSlot::JoySlotInputAction mode, QWidget *parent = nullptr); int getMouseCode() const; JoyButtonSlot::JoySlotInputAction getMouseMode() const; signals: void mouseSlotCreated(JoyButtonSlot *tempslot); private slots: void createTempSlot(); private: int code; JoyButtonSlot::JoySlotInputAction mode; }; #endif // VIRTUALMOUSEPUSHBUTTON_H AntiMicroX-antimicrox-b300273/src/localantimicroserver.cpp000066400000000000000000000075001471077622000236760ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "localantimicroserver.h" #include "common.h" #include #include #include LocalAntiMicroServer::LocalAntiMicroServer(QObject *parent) : QObject(parent) { localServer = new QLocalServer(this); } void LocalAntiMicroServer::startLocalServer() { if (localServer != nullptr) { bool removedServer = QLocalServer::removeServer(PadderCommon::localSocketKey); if (!removedServer) qDebug() << "Couldn't remove local server named " << PadderCommon::localSocketKey; if (localServer->maxPendingConnections() != 1) localServer->setMaxPendingConnections(1); if (!localServer->isListening()) { if (!localServer->listen(PadderCommon::localSocketKey)) { QString message("Could not start signal server. Profiles cannot be reloaded\n"); message.append("from command-line"); PRINT_STDERR() << tr(message.toStdString().c_str()) << "\n"; qDebug() << "Could not start signal server. Profiles cannot be reloaded\n" << " \nfrom command-line\n " << tr(message.toStdString().c_str()); } else { connect(localServer, &QLocalServer::newConnection, this, &LocalAntiMicroServer::handleOutsideConnection); } } } else { qDebug() << "LocalAntiMicroXServer::startLocalServer(): localServer is nullptr"; } } void LocalAntiMicroServer::handleOutsideConnection() { if (localServer != nullptr) { QLocalSocket *socket = localServer->nextPendingConnection(); if (socket != nullptr) { qDebug() << "There is next pending connection: " << socket->socketDescriptor(); connect(socket, &QLocalSocket::disconnected, this, &LocalAntiMicroServer::handleSocketDisconnect); connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater); checkForMessages(socket); } else { qDebug() << "There isn't next pending connection: "; } } else { qDebug() << "LocalAntiMicroXServer::handleOutsideConnection(): localServer is nullptr"; } } void LocalAntiMicroServer::handleSocketDisconnect() { emit clientdisconnect(); } void LocalAntiMicroServer::close() { localServer->close(); } void LocalAntiMicroServer::checkForMessages(QLocalSocket *socket) { DEBUG() << "Waiting for message"; socket->waitForConnected(50); bool result = socket->waitForReadyRead(200); DEBUG() << "Waiting for message ended with result: " << (result ? "true" : "false"); if (result) { QString msg = QString(socket->readLine(30)); DEBUG() << "Received external message:" << msg; if (msg == PadderCommon::unhideCommand) { DEBUG() << "Showing hidden window because of external request"; emit showHiddenWindow(); } } } QLocalServer *LocalAntiMicroServer::getLocalServer() const { return localServer; } AntiMicroX-antimicrox-b300273/src/localantimicroserver.h000066400000000000000000000030401471077622000233360ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef LOCALANTIMICROSERVER_H #define LOCALANTIMICROSERVER_H #include #include class QLocalServer; /** * @brief Class used for checking presence of other AntiMicroX instances and communicating with them. */ class LocalAntiMicroServer : public QObject { Q_OBJECT public: explicit LocalAntiMicroServer(QObject *parent = nullptr); QLocalServer *getLocalServer() const; signals: void clientdisconnect(); void showHiddenWindow(); public slots: void startLocalServer(); void handleOutsideConnection(); void handleSocketDisconnect(); void close(); private: void checkForMessages(QLocalSocket *socket); QLocalServer *localServer; }; #endif // LOCALANTIMICROSERVER_H AntiMicroX-antimicrox-b300273/src/logger.cpp000066400000000000000000000176601471077622000207360ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2021 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "logger.h" #include #include #include // only for QT 6 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #include #endif #include #include Logger *Logger::instance = nullptr; /** * @brief Outputs log messages to a given text stream. Client code * should determine whether it points to a console stream or * to a file. * @param stream used to output text * @param output_lvl Messages based of a given output level or lower will be logged * @param parent object */ Logger::Logger(QTextStream *stream, LogLevel output_lvl, QObject *parent) : QObject(parent) { // needed to allow sending LogLevel using signals and slots qRegisterMetaType("Logger::LogLevel"); loggingThread = new QThread(this); loggingThread->setObjectName("loggingThread"); outputStream = stream; outputLevel = output_lvl; this->moveToThread(loggingThread); loggingThread->start(); } /** * @brief Close output stream and set instance to 0. */ Logger::~Logger() { VERBOSE() << "Closing logger"; // To be sure about proper processing logs before deleting logger std::this_thread::sleep_for(std::chrono::milliseconds(30)); loggingThread->quit(); loggingThread->wait(); closeLogger(); instance = nullptr; } /** * @brief Set the highest logging level. Determines which messages * are output to the output stream. * @param level Highest log level utilized. */ void Logger::setLogLevel(LogLevel level) { Q_ASSERT(instance != nullptr); QMutexLocker locker(&instance->logMutex); Q_UNUSED(locker); instance->outputLevel = level; } /** * @brief Get the current output level associated with the logger. * @return Current output level */ Logger::LogLevel Logger::getCurrentLogLevel() { Q_ASSERT(instance != nullptr); return instance->outputLevel; } void Logger::setCurrentStream(QTextStream *stream) { Q_ASSERT(instance != nullptr); QMutexLocker locker(&instance->logMutex); Q_UNUSED(locker); instance->outputStream->flush(); instance->outputStream = stream; } QTextStream *Logger::getCurrentStream() { Q_ASSERT(instance != nullptr); return instance->outputStream; } /** * @brief Flushes output stream and closes stream if requested. * @param closeStream Whether to close the current stream. Defaults to true. */ void Logger::closeLogger(bool closeStream) { if (outputStream != nullptr) { outputStream->flush(); if (closeStream && (outputStream->device() != nullptr)) { QIODevice *device = outputStream->device(); if (device->isOpen()) { device->close(); } } } } /** * @brief Write an individual message to the text stream. * * This socket method is executed in separate logging thread */ void Logger::logMessage(const QString &message, const Logger::LogLevel level, const uint lineno, const QString &filename) { const static QMap TYPE_NAMES = { {LogLevel::LOG_DEBUG, "🐞DEBUG"}, {LogLevel::LOG_VERBOSE, "⚪VERBOSE"}, {LogLevel::LOG_INFO, "🟢INFO"}, {LogLevel::LOG_WARNING, "❗WARN"}, {LogLevel::LOG_ERROR, "❌ERROR"}, {LogLevel::LOG_NONE, "NONE"}}; QString displayTime = QString("[%1] ").arg(QTime::currentTime().toString("hh:mm:ss.zzz")); if ((outputLevel != LOG_NONE) && (level <= outputLevel)) { bool extendedLogs = (outputLevel == LOG_DEBUG); if (extendedLogs) *outputStream << displayTime; QString finalMessage = message; finalMessage = finalMessage.replace("\n", "\n\t\t\t"); *outputStream << TYPE_NAMES[level] << "\t" << finalMessage; if (extendedLogs) { static int filename_offset = -1; if (filename_offset < 0) { filename_offset = filename.lastIndexOf("/src/"); } if (lineno != 0) *outputStream << " (file " << filename.mid(filename_offset) << ":" << lineno << ")"; } *outputStream << "\n"; outputStream->flush(); } } void Logger::setCurrentLogFile(QString filename) { if (filename.isEmpty()) return; Q_ASSERT(instance != nullptr); if (instance->outputFile.isOpen()) { instance->closeLogger(true); } instance->outputFile.setFileName(filename); if (!instance->outputFile.open(QIODevice::WriteOnly)) { qCritical() << "Couldn't open log file: " << filename; return; } instance->outFileStream.setDevice(&instance->outputFile); #if defined(Q_OS_WIN) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) instance->outFileStream.setEncoding(QStringConverter::Utf8); #else instance->outFileStream.setCodec("UTF-8"); // to properly print special characters in files #endif #endif instance->setCurrentStream(&instance->outFileStream); } bool Logger::isWritingToFile() { return outputFile.isOpen(); } /** * @brief log message handling function * * It is meant to be registered via qInstallMessageHandler() at the beginning of application * * @param type * @param context * @param msg */ void Logger::loggerMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { if (Logger::instance != nullptr) { Logger::LogLevel level = Logger::instance->getCurrentLogLevel(); if (level == LogLevel::LOG_NONE) return; switch (type) { case QtDebugMsg: if (level >= Logger::LOG_DEBUG || level == Logger::LOG_MAX) LogHelper(LogLevel::LOG_DEBUG, context.line, context.file, msg); break; case QtInfoMsg: if (level >= Logger::LOG_INFO) LogHelper(LogLevel::LOG_INFO, context.line, context.file, msg); break; case QtWarningMsg: if (level >= Logger::LOG_WARNING) LogHelper(LogLevel::LOG_WARNING, context.line, context.file, msg); break; case QtCriticalMsg: if (level >= Logger::LOG_ERROR) LogHelper(LogLevel::LOG_ERROR, context.line, context.file, msg); break; case QtFatalMsg: if (level >= Logger::LOG_ERROR) LogHelper(LogLevel::LOG_ERROR, context.line, context.file, msg); abort(); default: break; } } } /** * @brief Create instance of logger, if there is any other instance it will de deleted * * @return Logger* - pointer to newly created instance */ Logger *Logger::createInstance(QTextStream *stream, LogLevel outputLevel, QObject *parent) { if (instance != nullptr) { delete instance; } instance = new Logger(stream, outputLevel, parent); return instance; } bool Logger::isDebugEnabled() { if (instance != nullptr) { return instance->outputLevel == LogLevel::LOG_DEBUG; } return false; } QString Logger::getCurrentLogFile() { Q_ASSERT(instance != nullptr); if (instance->outputFile.exists()) return instance->outputFile.fileName(); else return ""; }AntiMicroX-antimicrox-b300273/src/logger.h000066400000000000000000000157351471077622000204040ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef LOGGER_H #define LOGGER_H #include #include #include #include #include #include /** * @brief Macro used for printing messages to stdout * * Example usage * PRINT_STDOUT() << "my message"; * */ #define PRINT_STDOUT() StreamPrinter(stdout, __LINE__, __FILE__) #define PRINT_STDERR() StreamPrinter(stderr, __LINE__, __FILE__) #define DEBUG() LogHelper(Logger::LogLevel::LOG_DEBUG, __LINE__, __FILE__) #define VERBOSE() LogHelper(Logger::LogLevel::LOG_VERBOSE, __LINE__, __FILE__) #define INFO() LogHelper(Logger::LogLevel::LOG_INFO, __LINE__, __FILE__) #define WARN() LogHelper(Logger::LogLevel::LOG_WARNING, __LINE__, __FILE__) #define ERROR() LogHelper(Logger::LogLevel::LOG_ERROR, __LINE__, __FILE__) /** * @brief Custom singleton class used for logging across application. * * It manages log-levels, formatting, printing logs and saving them to file. * Logs across the program can be written using * Local macros(better support for showing log location in release builds): * DEBUG(), INFO(), VERBOSE(), WARN(), ERROR() * QT macros: * qDebug(), qInfo(), qWarning(), qCritical, and qFatal() * */ class Logger : public QObject { Q_OBJECT Q_ENUMS(LogLevel) public: enum LogLevel { LOG_NONE = 0, LOG_ERROR = 1, LOG_WARNING = 2, LOG_INFO = 3, LOG_VERBOSE = 4, LOG_DEBUG = 5, LOG_MAX = LOG_DEBUG }; ~Logger(); static void loggerMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg); static void setLogLevel(LogLevel level); LogLevel getCurrentLogLevel(); static bool isDebugEnabled(); static void setCurrentStream(QTextStream *stream); static void setCurrentLogFile(QString filename); static QString getCurrentLogFile(); bool isWritingToFile(); static QTextStream *getCurrentStream(); /** * @brief Get the Instance of logger * * @param raiseExceptionForNull - raise std::runtime_error when instance doesn't exist * @return Logger* */ inline static Logger *getInstance(bool raiseExceptionForNull = true) { if (raiseExceptionForNull && instance == nullptr) { throw std::runtime_error("There is no logger instance"); } return instance; } static Logger *createInstance(QTextStream *stream = nullptr, LogLevel outputLevel = LOG_INFO, QObject *parent = nullptr); protected: explicit Logger(QTextStream *stream, LogLevel output_lvl = LOG_INFO, QObject *parent = nullptr); void closeLogger(bool closeStream = true); static Logger *instance; QFile outputFile; QTextStream outFileStream; QTextStream *outputStream; LogLevel outputLevel; QMutex logMutex; QThread *loggingThread; // in this thread all of writing operations will be executed public slots: void logMessage(const QString &message, const Logger::LogLevel level, const uint lineno, const QString &filename); }; /** * @brief simple helper class used for constructing log message and sending it to Logger * * Message is sent either by using sendMessage(), or during destruction. */ class LogHelper : public QObject { Q_OBJECT public: QString message; Logger::LogLevel level; uint lineno; QString filename; bool is_message_sent; Logger::LogLevel log_level; LogHelper(const Logger::LogLevel level, const uint lineno, const QString &filename, const QString &message = "") : message(message) , level(level) , lineno(lineno) , filename(filename) , is_message_sent(false) { Logger *pointer = Logger::getInstance(); log_level = pointer->getCurrentLogLevel(); connect(this, &LogHelper::logMessage, pointer, &Logger::logMessage); }; ~LogHelper() { if (!is_message_sent) sendMessage(); } void sendMessage() { is_message_sent = true; emit logMessage(message, level, lineno, filename); }; LogHelper &operator<<(const QString &s) { if (log_level != Logger::LogLevel::LOG_NONE) message = message + s; return *this; }; template LogHelper &operator<<(Message ch) { if (log_level != Logger::LogLevel::LOG_NONE) { // The simplest way of building string from possible variables std::stringstream str; str << ch; message = message + str.str().c_str(); } return *this; } signals: void logMessage(const QString &message, const Logger::LogLevel level, const uint lineno, const QString &filename); }; /** * @brief Simple adapter for QTextStream additionally logging printed values * Logs are printed when StreamPrinter is destroyed or logContent() is called * * Recommended usage with macros PRINT_STDOUT() and PRINT_STDERR() */ class StreamPrinter : public QObject { Q_OBJECT private: QTextStream m_stream; std::stringstream m_message; uint m_lineno; QString m_filename; public: StreamPrinter(FILE *file, uint lineno = 0, QString filename = "") : m_stream(file) , m_message("") , m_lineno(lineno) , m_filename(filename) { if (file == stdout) { m_message << "Printed stdout message📓: "; } else if (file == stderr) { m_message << "Printed stderr message📓: "; } else { m_message << "unknown stream "; } }; ~StreamPrinter() { // When logger prints to stream, then we already have printed messages into console, // there is no need to duplicate if (Logger::getInstance()->isWritingToFile()) LogHelper(Logger::LogLevel::LOG_INFO, m_lineno, m_filename, QString(m_message.str().c_str())).sendMessage(); }; template StreamPrinter &operator<<(Message ch) { m_stream << ch; m_message << ch; return *this; } StreamPrinter &operator<<(const QString &s) { m_stream << s; m_message << s.toStdString(); return *this; }; }; #endif // LOGGER_H AntiMicroX-antimicrox-b300273/src/main.cpp000066400000000000000000000506331471077622000204000ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2021 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "antimicrosettings.h" #include "antkeymapper.h" #include "applaunchhelper.h" #include "autoprofileinfo.h" #include "commandlineutility.h" #include "common.h" #include "inputdaemon.h" #include "inputdevice.h" #include "joybuttonslot.h" #include "joysensordirection.h" #include "joysensortype.h" #include "localantimicroserver.h" #include "mainwindow.h" #include "setjoystick.h" #include "simplekeygrabberbutton.h" #include "eventhandlerfactory.h" #include "logger.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef Q_OS_UNIX #include #include #include #ifdef WITH_X11 #include "x11extras.h" #endif static void termSignalTermHandler(int signal) { Q_UNUSED(signal) qDebug() << "Received SIGTERM. Closing..."; qApp->exit(0); } static void termSignalIntHandler(int signal) { Q_UNUSED(signal) qDebug() << "Received SIGINT. Closing..."; qApp->exit(0); } static void termSignalSegfaultHandler(int signal) { if (signal == SIGSEGV) ERROR() << "Received SIGSEGV (segmentation fault)"; else if (signal == SIGABRT) ERROR() << "Received SIGABRT (abort)"; else ERROR() << "Received signal with number" << signal; const int MAX_NUM = 32; void *array[MAX_NUM]; size_t size; // get void*'s for all entries on the stack size = backtrace(array, MAX_NUM); char **strings = backtrace_symbols(array, size); WARN() << "Stack trace:"; for (size_t i = 0; i < size; i++) { WARN() << strings[i] << "\t"; } free(strings); // Restore default handler struct sigaction segint; segint.sa_handler = SIG_DFL; sigemptyset(&segint.sa_mask); segint.sa_flags = 0; sigaction(signal, &segint, nullptr); delete Logger::getInstance(); } void installSignalHandlers() { // Have program handle SIGTERM struct sigaction termaction; termaction.sa_handler = &termSignalTermHandler; sigemptyset(&termaction.sa_mask); termaction.sa_flags = 0; sigaction(SIGTERM, &termaction, nullptr); // Have program handle SIGINT struct sigaction termint; termint.sa_handler = &termSignalIntHandler; sigemptyset(&termint.sa_mask); termint.sa_flags = 0; sigaction(SIGINT, &termint, nullptr); // Have program handle SIGSEGV struct sigaction segint; segint.sa_handler = &termSignalSegfaultHandler; sigemptyset(&segint.sa_mask); segint.sa_flags = 0; sigaction(SIGSEGV, &segint, nullptr); // Have program handle SIGABRT struct sigaction segabrt; segabrt.sa_handler = &termSignalSegfaultHandler; sigemptyset(&segabrt.sa_mask); segabrt.sa_flags = 0; sigaction(SIGABRT, &segabrt, nullptr); } #endif // was non static static void deleteInputDevices(QMap *joysticks) { QMapIterator iter(*joysticks); while (iter.hasNext()) { InputDevice *joystick = iter.next().value(); if (joystick != nullptr) { delete joystick; joystick = nullptr; } } joysticks->clear(); } /** * @brief Function used for copying settings used by antimicro and * previous revisions of antimicrox to provide backward compatibility */ void importLegacySettingsIfExist() { qDebug() << "Importing settings"; const QFileInfo config(PadderCommon::configFilePath()); const bool configExists = config.exists() && config.isFile(); // 'antimicroX' const QFileInfo legacyConfig(PadderCommon::configLegacyFilePath()); const bool legacyConfigExists = legacyConfig.exists() && legacyConfig.isFile(); // 'antimicro' const QFileInfo legacyAntimicroConfig(PadderCommon::configAntimicroLegacyFilePath()); const bool legacyAntimicroConfigExists = legacyAntimicroConfig.exists() && legacyAntimicroConfig.isFile(); const bool requireMigration = !configExists && (legacyConfigExists || legacyAntimicroConfigExists); if (requireMigration) { const QFileInfo fileToCopy = legacyConfigExists ? legacyConfig : legacyAntimicroConfig; #if defined(Q_OS_WIN) const QString location = PadderCommon::configPath(); #else const QString location = "~/.config/antimicrox"; #endif QDir(PadderCommon::configPath()).mkpath(PadderCommon::configPath()); const bool copySuccess = QFile::copy(fileToCopy.canonicalFilePath(), PadderCommon::configFilePath()); qDebug() << "Legacy settings found"; const QString successMessage = QObject::tr("Your original settings (previously stored in %1) have been copied to\n%2\n If you want you can " "delete the original directory or leave it as it is.") .arg(fileToCopy.canonicalFilePath(), location); const QString errorMessage = QObject::tr("Some problem with settings migration occurred.\nOriginal configs are stored in \n%1\n but their " "new location is: \n%2\nYou can migrate manually by renaming old directory and renaming file to " "antimicrox_settings.ini.") .arg(fileToCopy.canonicalFilePath(), location); QMessageBox msgBox; if (copySuccess) { qDebug() << "Legacy settings copied"; msgBox.setText(successMessage); } else { qWarning() << "Problem with importing settings from: " << fileToCopy.canonicalFilePath() << " to: " << PadderCommon::configFilePath(); msgBox.setText(errorMessage); } msgBox.exec(); } } int main(int argc, char *argv[]) { qInstallMessageHandler(Logger::loggerMessageHandler); QApplication antimicrox(argc, argv); QCoreApplication::setApplicationName("antimicrox"); QCoreApplication::setApplicationVersion(PadderCommon::programVersion); QTextStream outstream(stdout); Logger *appLogger = Logger::createInstance(&outstream, Logger::LogLevel::LOG_WARNING); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType("SDL_JoystickID"); qRegisterMetaType("JoyButtonSlot::JoySlotInputAction"); qRegisterMetaType(); qRegisterMetaType(); #if defined(WITH_X11) if (QApplication::platformName() == QStringLiteral("xcb")) { XInitThreads(); } #endif importLegacySettingsIfExist(); AntiMicroSettings settings(PadderCommon::configFilePath(), QSettings::IniFormat); CommandLineUtility cmdutility; try { cmdutility.parseArguments(antimicrox); } catch (const std::runtime_error &e) { std::cerr << e.what() << '\n'; std::cerr << "Closing\n"; return -1; } settings.importFromCommandLine(cmdutility); settings.applySettingsToLogger(cmdutility, appLogger); Q_INIT_RESOURCE(resources); QDir configDir(PadderCommon::configPath()); if (!configDir.exists()) { configDir.mkpath(PadderCommon::configPath()); } QMap *joysticks = new QMap(); QThread *inputEventThread = nullptr; // Cross-platform way of performing IPC. Currently, // only establish a connection and then disconnect. // In the future, there might be a reason to actually send // messages to the QLocalServer. QLocalSocket socket; PadderCommon::log_system_config(); if ((socket.serverName() == QString())) { socket.connectToServer(PadderCommon::localSocketKey); if (!socket.waitForConnected(3000)) { qDebug() << "Socket's state: " << socket.state(); qDebug() << "Server name: " << socket.serverName(); qDebug() << "Socket descriptor: " << socket.socketDescriptor(); qDebug() << "The connection hasn't been established: \nerror text -> " << socket.error() << "\nerror text 2 ->" << socket.errorString(); } else { qDebug() << "Socket connected"; } } else { socket.abort(); } if (!socket.isValid()) { qDebug() << "Socket is not valid"; qDebug() << "Socket's state: " << socket.state(); qDebug() << "Server name: " << socket.serverName(); qDebug() << "Socket descriptor: " << socket.socketDescriptor(); } if (socket.state() == QLocalSocket::ConnectedState) { // An instance of this program is already running. // Save app config and exit. PRINT_STDOUT() << "AntiMicroX is already running.\n"; QPointer joypad_worker = new InputDaemon(joysticks, &settings, false); MainWindow mainWindow(joysticks, &cmdutility, &settings, false); mainWindow.fillButtons(); mainWindow.alterConfigFromSettings(); if (cmdutility.hasProfile() || cmdutility.hasProfileInOptions()) { PRINT_STDOUT() << "Update selected profile\n"; mainWindow.saveAppConfig(); } else if (cmdutility.isUnloadRequested()) { mainWindow.saveAppConfig(); } else if (cmdutility.isShowRequested()) { INFO() << "Showing window if hidden.\n"; socket.write(PadderCommon::unhideCommand.toStdString().c_str()); socket.waitForBytesWritten(100); } qDebug() << "Closing this app instance"; mainWindow.removeJoyTabs(); QObject::connect(&antimicrox, &QApplication::aboutToQuit, joypad_worker.data(), &InputDaemon::quit); #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) QTimer::singleShot(50, &antimicrox, &QApplication::quit); #else QTimer::singleShot(50, &antimicrox, SLOT(quit())); #endif int result = antimicrox.exec(); settings.sync(); socket.disconnectFromServer(); if (socket.state() == QLocalSocket::LocalSocketState::ConnectedState || socket.state() == QLocalSocket::LocalSocketState::ClosingState) { if (socket.waitForDisconnected(2000)) qDebug() << "Socket " << socket.socketDescriptor() << " disconnected!"; } else qDebug() << "Socket " << socket.socketDescriptor() << " disconnected!"; deleteInputDevices(joysticks); delete joysticks; joysticks = nullptr; if (!joypad_worker.isNull()) { delete joypad_worker; joypad_worker.clear(); } delete appLogger; return result; } LocalAntiMicroServer *localServer = new LocalAntiMicroServer(); localServer->startLocalServer(); #if defined(Q_OS_WIN) qApp->setStyle("fusion"); #endif antimicrox.setQuitOnLastWindowClosed(false); QStringList appDirsLocations = QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation); appDirsLocations.append(QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation)); QStringList themePathsTries = QStringList(); for (QList::const_iterator i = appDirsLocations.constBegin(); i != appDirsLocations.constEnd(); ++i) { themePathsTries.append(QString("%1%2").arg(*i).arg("/icons")); qDebug() << QString("%1%2").arg(*i).arg("/icons"); } QIcon::setThemeSearchPaths(themePathsTries); qDebug() << "Theme name: " << QIcon::themeName(); // Update log info based on config values if (cmdutility.getCurrentLogLevel() == Logger::LOG_NONE && settings.contains("LogLevel")) { appLogger->setLogLevel(static_cast(settings.value("LogLevel").toInt())); } if (cmdutility.getCurrentLogFile().isEmpty() && settings.contains("LogFile")) { appLogger->setCurrentLogFile(settings.value("LogFile").toString()); } QString targetLang = QLocale::system().name(); if (settings.contains("Language")) { targetLang = settings.value("Language").toString(); } QTranslator qtTranslator; #if defined(Q_OS_UNIX) installSignalHandlers(); QString transPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath); if (QDir(transPath).entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries).count() == 0) { qtTranslator.load(QString("qt_").append(targetLang), "/app/share/antimicrox/translations"); } else { qtTranslator.load(QString("qt_").append(targetLang), transPath); } #endif antimicrox.installTranslator(&qtTranslator); QTranslator myappTranslator; if (QDir("/app/share/antimicrox").entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries).count() > 0) { myappTranslator.load(QString("antimicrox_").append(targetLang), "app/share/antimicrox/translations"); } else { myappTranslator.load(QString("antimicrox_").append(targetLang), QApplication::applicationDirPath().append("/../share/antimicrox/translations")); } antimicrox.installTranslator(&myappTranslator); if (cmdutility.shouldListControllers()) { QPointer joypad_worker = new InputDaemon(joysticks, &settings, false); AppLaunchHelper mainAppHelper(&settings, false); mainAppHelper.printControllerList(joysticks); joypad_worker->quit(); delete joysticks; joysticks = nullptr; delete localServer; localServer = nullptr; #ifdef WITH_X11 if (QApplication::platformName() == QStringLiteral("xcb")) { X11Extras::getInstance()->closeDisplay(); } #endif delete appLogger; return 0; } bool status = true; QString eventGeneratorIdentifier = QString(); AntKeyMapper *keyMapper = nullptr; EventHandlerFactory *factory = EventHandlerFactory::getInstance(cmdutility.getEventGenerator()); if (!factory) { status = false; } else { eventGeneratorIdentifier = factory->handler()->getIdentifier(); keyMapper = AntKeyMapper::getInstance(eventGeneratorIdentifier); status = factory->handler()->init(); factory->handler()->printPostMessages(); } #if defined(WITH_UINPUT) && defined(WITH_XTEST) // Use fallback event handler. if (!status && cmdutility.getEventGenerator() != EventHandlerFactory::fallBackIdentifier()) { QString eventDisplayName = EventHandlerFactory::handlerDisplayName(EventHandlerFactory::fallBackIdentifier()); qInfo() << QObject::tr("Attempting to use fallback option %1 for event generation.").arg(eventDisplayName); if (keyMapper != nullptr) { keyMapper->deleteInstance(); keyMapper = nullptr; } factory->deleteInstance(); factory = EventHandlerFactory::getInstance(EventHandlerFactory::fallBackIdentifier()); if (!factory) { status = false; } else { eventGeneratorIdentifier = factory->handler()->getIdentifier(); keyMapper = AntKeyMapper::getInstance(eventGeneratorIdentifier); status = factory->handler()->init(); factory->handler()->printPostMessages(); } } #endif if (!status) { PRINT_STDERR() << QObject::tr("Failed to open event generator. Exiting.") << "\n"; deleteInputDevices(joysticks); delete joysticks; joysticks = nullptr; delete localServer; localServer = nullptr; if (keyMapper != nullptr) { keyMapper->deleteInstance(); keyMapper = nullptr; } #if defined(WITH_X11) if (QApplication::platformName() == QStringLiteral("xcb")) { X11Extras::getInstance()->closeDisplay(); } #endif delete appLogger; return EXIT_FAILURE; } qInfo() << QObject::tr("Using %1 as the event generator.").arg(factory->handler()->getName()); #ifdef Q_OS_WIN PadderCommon::log_system_config(); // workaround for missing windows logs #endif QPointer joypad_worker = new InputDaemon(joysticks, &settings); inputEventThread = new QThread(); inputEventThread->setObjectName("inputEventThread"); MainWindow *mainWindow = new MainWindow(joysticks, &cmdutility, &settings); mainWindow->setAppTranslator(&qtTranslator); mainWindow->setTranslator(&myappTranslator); AppLaunchHelper mainAppHelper(&settings, mainWindow->getGraphicalStatus()); QObject::connect(mainWindow, &MainWindow::joystickRefreshRequested, joypad_worker.data(), &InputDaemon::refresh); QObject::connect(joypad_worker.data(), &InputDaemon::joystickRefreshed, mainWindow, &MainWindow::fillButtonsID); QObject::connect(joypad_worker.data(), &InputDaemon::joysticksRefreshed, mainWindow, &MainWindow::fillButtonsMap); QObject::connect(&antimicrox, &QApplication::aboutToQuit, localServer, &LocalAntiMicroServer::close); QObject::connect(&antimicrox, &QApplication::aboutToQuit, mainWindow, &MainWindow::saveAppConfig); QObject::connect(&antimicrox, &QApplication::aboutToQuit, mainWindow, &MainWindow::removeJoyTabs); QObject::connect(&antimicrox, &QApplication::aboutToQuit, &mainAppHelper, &AppLaunchHelper::revertMouseThread); QObject::connect(&antimicrox, &QApplication::aboutToQuit, joypad_worker.data(), &InputDaemon::quit); QObject::connect(&antimicrox, &QApplication::aboutToQuit, joypad_worker.data(), &InputDaemon::deleteLater); QObject::connect(localServer, &LocalAntiMicroServer::showHiddenWindow, mainWindow, &MainWindow::show); QObject::connect(localServer, &LocalAntiMicroServer::clientdisconnect, mainWindow, &MainWindow::handleInstanceDisconnect); QObject::connect(mainWindow, &MainWindow::mappingUpdated, joypad_worker.data(), &InputDaemon::refreshMapping); QObject::connect(joypad_worker.data(), &InputDaemon::deviceUpdated, mainWindow, &MainWindow::testMappingUpdateNow); QObject::connect(joypad_worker.data(), &InputDaemon::deviceRemoved, mainWindow, &MainWindow::removeJoyTab); QObject::connect(joypad_worker.data(), &InputDaemon::deviceAdded, mainWindow, &MainWindow::addJoyTab); mainAppHelper.initRunMethods(); QTimer::singleShot(0, mainWindow, SLOT(fillButtons())); QTimer::singleShot(0, mainWindow, SLOT(alterConfigFromSettings())); QTimer::singleShot(0, mainWindow, SLOT(changeWindowStatus())); mainAppHelper.changeMouseThread(inputEventThread); joypad_worker->startWorker(); joypad_worker->moveToThread(inputEventThread); PadderCommon::mouseHelperObj.moveToThread(inputEventThread); inputEventThread->start(QThread::HighPriority); int app_result = antimicrox.exec(); qInfo() << QObject::tr("Quitting Program"); delete localServer; localServer = nullptr; if (!joypad_worker.isNull()) { joypad_worker->deleteLater(); } inputEventThread->quit(); inputEventThread->wait(); delete inputEventThread; inputEventThread = nullptr; delete joysticks; joysticks = nullptr; AntKeyMapper::getInstance()->deleteInstance(); #if defined(WITH_X11) if (QApplication::platformName() == QStringLiteral("xcb")) { X11Extras::getInstance()->closeDisplay(); } #endif EventHandlerFactory::getInstance()->handler()->cleanup(); EventHandlerFactory::getInstance()->deleteInstance(); delete mainWindow; mainWindow = nullptr; delete appLogger; return app_result; } AntiMicroX-antimicrox-b300273/src/mousedialog/000077500000000000000000000000001471077622000212515ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/mousedialog/mouseaxissettingsdialog.cpp000066400000000000000000000346131471077622000267420ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mouseaxissettingsdialog.h" #include "common.h" #include "inputdevice.h" #include "joyaxis.h" #include "setjoystick.h" #include "springmoderegionpreview.h" #include "springmousemoveinfo.h" #include #include #include MouseAxisSettingsDialog::MouseAxisSettingsDialog(JoyAxis *axis, QWidget *parent) : MouseSettingsDialog(parent) , helper(axis) { setAttribute(Qt::WA_DeleteOnClose); this->axis = axis; getHelperLocal().moveToThread(axis->thread()); calculateMouseSpeedPreset(); selectCurrentMouseModePreset(); calculateSpringPreset(); if (axis->getButtonsPresetSensitivity() > 0.0) { ui->sensitivityDoubleSpinBox->setValue(axis->getButtonsPresetSensitivity()); } updateAccelerationCurvePresetComboBox(); updateWindowTitleAxisName(); if (ui->mouseModeComboBox->currentIndex() == 2) { springPreviewWidget = new SpringModeRegionPreview(ui->springWidthSpinBox->value(), ui->springHeightSpinBox->value()); } else { springPreviewWidget = new SpringModeRegionPreview(0, 0); } calculateWheelSpeedPreset(); if (axis->isRelativeSpring()) { ui->relativeSpringCheckBox->setChecked(true); } double easingDuration = axis->getButtonsEasingDuration(); ui->easingDoubleSpinBox->setValue(easingDuration); calculateExtraAccelrationStatus(); calculateExtraAccelerationMultiplier(); calculateStartAccelerationMultiplier(); calculateMinAccelerationThreshold(); calculateMaxAccelerationThreshold(); calculateAccelExtraDuration(); calculateReleaseSpringRadius(); calculateExtraAccelerationCurve(); changeSpringSectionStatus(ui->mouseModeComboBox->currentIndex()); changeSettingsWidgetStatus(ui->accelerationComboBox->currentIndex()); connect(this, &MouseAxisSettingsDialog::finished, springPreviewWidget, &SpringModeRegionPreview::deleteLater); connect(ui->mouseModeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseAxisSettingsDialog::changeMouseMode); connect(ui->accelerationComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseAxisSettingsDialog::changeMouseCurve); connect(ui->horizontalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseAxisSettingsDialog::updateConfigHorizontalSpeed); connect(ui->verticalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseAxisSettingsDialog::updateConfigVerticalSpeed); connect(ui->springWidthSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseAxisSettingsDialog::updateSpringWidth); connect(ui->springWidthSpinBox, static_cast(&QSpinBox::valueChanged), springPreviewWidget, &SpringModeRegionPreview::setSpringWidth); connect(ui->springHeightSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseAxisSettingsDialog::updateSpringHeight); connect(ui->springHeightSpinBox, static_cast(&QSpinBox::valueChanged), springPreviewWidget, &SpringModeRegionPreview::setSpringHeight); connect(ui->relativeSpringCheckBox, &QCheckBox::clicked, this, &MouseAxisSettingsDialog::updateSpringRelativeStatus); connect(ui->sensitivityDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &MouseAxisSettingsDialog::updateSensitivity); connect(ui->wheelHoriSpeedSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseAxisSettingsDialog::updateWheelSpeedHorizontalSpeed); connect(ui->wheelVertSpeedSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseAxisSettingsDialog::updateWheelSpeedVerticalSpeed); connect(ui->easingDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), axis, &JoyAxis::setButtonsEasingDuration); connect(ui->extraAccelerationGroupBox, &QGroupBox::clicked, &helper, &MouseAxisSettingsDialogHelper::updateExtraAccelerationStatus); connect(ui->extraAccelDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseAxisSettingsDialogHelper::updateExtraAccelerationMultiplier); connect(ui->minMultiDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseAxisSettingsDialogHelper::updateStartMultiPercentage); connect(ui->minThresholdDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseAxisSettingsDialogHelper::updateMinAccelThreshold); connect(ui->maxThresholdDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseAxisSettingsDialogHelper::updateMaxAccelThreshold); connect(ui->accelExtraDurationDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseAxisSettingsDialogHelper::updateAccelExtraDuration); connect(ui->releaseSpringRadiusspinBox, static_cast(&QSpinBox::valueChanged), &helper, &MouseAxisSettingsDialogHelper::updateReleaseSpringRadius); connect(ui->extraAccelCurveComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseAxisSettingsDialog::updateExtraAccelerationCurve); } void MouseAxisSettingsDialog::changeMouseMode(int index) { if (index == 1) { axis->setButtonsMouseMode(JoyButton::MouseCursor); if (springPreviewWidget->isVisible()) { springPreviewWidget->hide(); } } else if (index == 2) { axis->setButtonsMouseMode(JoyButton::MouseSpring); if (!springPreviewWidget->isVisible()) { springPreviewWidget->setSpringWidth(ui->springWidthSpinBox->value()); springPreviewWidget->setSpringHeight(ui->springHeightSpinBox->value()); } axis->getPAxisButton()->setExtraAccelerationStatus(false); axis->getNAxisButton()->setExtraAccelerationStatus(false); } } void MouseAxisSettingsDialog::changeMouseCurve(int index) { JoyButton::JoyMouseCurve temp = MouseSettingsDialog::getMouseCurveForIndex(index); axis->setButtonsMouseCurve(temp); } void MouseAxisSettingsDialog::updateConfigHorizontalSpeed(int value) { axis->getPAxisButton()->setMouseSpeedX(value); axis->getNAxisButton()->setMouseSpeedX(value); } void MouseAxisSettingsDialog::updateConfigVerticalSpeed(int value) { axis->getPAxisButton()->setMouseSpeedY(value); axis->getNAxisButton()->setMouseSpeedY(value); } void MouseAxisSettingsDialog::updateSpringWidth(int value) { axis->setButtonsSpringWidth(value); } void MouseAxisSettingsDialog::updateSpringHeight(int value) { axis->setButtonsSpringHeight(value); } void MouseAxisSettingsDialog::selectCurrentMouseModePreset() { bool presetDefined = axis->hasSameButtonsMouseMode(); if (presetDefined) { JoyButton::JoyMouseMovementMode mode = axis->getButtonsPresetMouseMode(); if (mode == JoyButton::MouseCursor) { ui->mouseModeComboBox->setCurrentIndex(1); } else if (mode == JoyButton::MouseSpring) { ui->mouseModeComboBox->setCurrentIndex(2); } } else { ui->mouseModeComboBox->setCurrentIndex(0); } } void MouseAxisSettingsDialog::calculateSpringPreset() { int tempWidth = axis->getButtonsPresetSpringWidth(); int tempHeight = axis->getButtonsPresetSpringHeight(); if (tempWidth > 0) { ui->springWidthSpinBox->setValue(tempWidth); } if (tempHeight > 0) { ui->springHeightSpinBox->setValue(tempHeight); } } void MouseAxisSettingsDialog::calculateMouseSpeedPreset() { int tempMouseSpeedX = 0; tempMouseSpeedX = qMax(axis->getPAxisButton()->getMouseSpeedX(), axis->getNAxisButton()->getMouseSpeedX()); int tempMouseSpeedY = 0; tempMouseSpeedY = qMax(axis->getPAxisButton()->getMouseSpeedY(), axis->getNAxisButton()->getMouseSpeedY()); ui->horizontalSpinBox->setValue(tempMouseSpeedX); ui->verticalSpinBox->setValue(tempMouseSpeedY); } void MouseAxisSettingsDialog::updateSensitivity(double value) { axis->setButtonsSensitivity(value); } void MouseAxisSettingsDialog::updateAccelerationCurvePresetComboBox() { JoyButton::JoyMouseCurve temp = axis->getButtonsPresetMouseCurve(); MouseSettingsDialog::updateAccelerationCurvePresetComboBox(temp); } void MouseAxisSettingsDialog::calculateWheelSpeedPreset() { JoyAxisButton *paxisbutton = axis->getPAxisButton(); JoyAxisButton *naxisbutton = axis->getNAxisButton(); int tempWheelSpeedX = qMax(paxisbutton->getWheelSpeedX(), naxisbutton->getWheelSpeedX()); int tempWheelSpeedY = qMax(paxisbutton->getWheelSpeedY(), naxisbutton->getWheelSpeedY()); ui->wheelHoriSpeedSpinBox->setValue(tempWheelSpeedX); ui->wheelVertSpeedSpinBox->setValue(tempWheelSpeedY); } void MouseAxisSettingsDialog::updateWheelSpeedHorizontalSpeed(int value) { axis->setButtonsWheelSpeedX(value); } void MouseAxisSettingsDialog::updateWheelSpeedVerticalSpeed(int value) { axis->setButtonsWheelSpeedY(value); } void MouseAxisSettingsDialog::updateSpringRelativeStatus(bool value) { axis->setButtonsSpringRelativeStatus(value); } void MouseAxisSettingsDialog::updateWindowTitleAxisName() { QString temp = QString(); temp.append(tr("Mouse Settings - ")); if (!axis->getAxisName().isEmpty()) { temp.append(axis->getPartialName(false, true)); } else { temp.append(axis->getPartialName()); } if (axis->getParentSet()->getIndex() != 0) { int setIndex = axis->getParentSet()->getRealIndex(); temp.append(" [").append(tr("Set %1").arg(setIndex)); QString setName = axis->getParentSet()->getName(); if (!setName.isEmpty()) { temp.append(": ").append(setName); } temp.append("]"); } setWindowTitle(temp); } void MouseAxisSettingsDialog::calculateExtraAccelrationStatus() { if ((axis->getPAxisButton()->isExtraAccelerationEnabled()) && (axis->getNAxisButton()->isExtraAccelerationEnabled())) { ui->extraAccelerationGroupBox->setChecked(true); } else { ui->extraAccelerationGroupBox->setChecked(false); } } void MouseAxisSettingsDialog::calculateExtraAccelerationMultiplier() { if (qFuzzyCompare(axis->getPAxisButton()->getExtraAccelerationMultiplier(), axis->getNAxisButton()->getExtraAccelerationMultiplier())) { double temp = axis->getPAxisButton()->getExtraAccelerationMultiplier(); ui->extraAccelDoubleSpinBox->setValue(temp); } } void MouseAxisSettingsDialog::calculateStartAccelerationMultiplier() { if (qFuzzyCompare(axis->getPAxisButton()->getStartAccelMultiplier(), axis->getNAxisButton()->getStartAccelMultiplier())) { double temp = axis->getPAxisButton()->getStartAccelMultiplier(); ui->minMultiDoubleSpinBox->setValue(temp); } } void MouseAxisSettingsDialog::calculateMinAccelerationThreshold() { if (qFuzzyCompare(axis->getPAxisButton()->getMinAccelThreshold(), axis->getNAxisButton()->getMinAccelThreshold())) { double temp = axis->getPAxisButton()->getMinAccelThreshold(); ui->minThresholdDoubleSpinBox->setValue(temp); } } void MouseAxisSettingsDialog::calculateMaxAccelerationThreshold() { if (qFuzzyCompare(axis->getPAxisButton()->getMaxAccelThreshold(), axis->getNAxisButton()->getMaxAccelThreshold())) { double temp = axis->getPAxisButton()->getMaxAccelThreshold(); ui->maxThresholdDoubleSpinBox->setValue(temp); } } void MouseAxisSettingsDialog::calculateAccelExtraDuration() { if (qFuzzyCompare(axis->getPAxisButton()->getAccelExtraDuration(), axis->getNAxisButton()->getAccelExtraDuration())) { double temp = axis->getPAxisButton()->getAccelExtraDuration(); ui->accelExtraDurationDoubleSpinBox->setValue(temp); } } void MouseAxisSettingsDialog::calculateReleaseSpringRadius() { int result = 0; if ((axis->getPAxisButton()->getSpringDeadCircleMultiplier()) == (axis->getNAxisButton()->getSpringDeadCircleMultiplier())) { result = axis->getPAxisButton()->getSpringDeadCircleMultiplier(); } ui->releaseSpringRadiusspinBox->setValue(result); } void MouseAxisSettingsDialog::updateExtraAccelerationCurve(int index) { JoyButton::JoyExtraAccelerationCurve temp = getExtraAccelCurveForIndex(index); if (index > 0) { PadderCommon::inputDaemonMutex.lock(); axis->getPAxisButton()->setExtraAccelerationCurve(temp); axis->getNAxisButton()->setExtraAccelerationCurve(temp); PadderCommon::inputDaemonMutex.unlock(); } } void MouseAxisSettingsDialog::calculateExtraAccelerationCurve() { if (axis->getPAxisButton()->getExtraAccelerationCurve() == axis->getNAxisButton()->getExtraAccelerationCurve()) { JoyButton::JoyExtraAccelerationCurve temp = axis->getPAxisButton()->getExtraAccelerationCurve(); updateExtraAccelerationCurvePresetComboBox(temp); } } JoyAxis *MouseAxisSettingsDialog::getAxis() const { return axis; } SpringModeRegionPreview *MouseAxisSettingsDialog::getSpringPreviewWidget() const { return springPreviewWidget; } MouseAxisSettingsDialogHelper const &MouseAxisSettingsDialog::getHelper() { return helper; } MouseAxisSettingsDialogHelper &MouseAxisSettingsDialog::getHelperLocal() { return helper; } AntiMicroX-antimicrox-b300273/src/mousedialog/mouseaxissettingsdialog.h000066400000000000000000000052531471077622000264050ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MOUSEAXISSETTINGSDIALOG_H #define MOUSEAXISSETTINGSDIALOG_H #include "ui_mousesettingsdialog.h" #include "mousesettingsdialog.h" #include "uihelpers/mouseaxissettingsdialoghelper.h" class JoyAxis; class SpringModeRegionPreview; class MouseAxisSettingsDialog : public MouseSettingsDialog { Q_OBJECT public: explicit MouseAxisSettingsDialog(JoyAxis *axis, QWidget *parent = nullptr); JoyAxis *getAxis() const; SpringModeRegionPreview *getSpringPreviewWidget() const; MouseAxisSettingsDialogHelper const &getHelper(); protected: void selectCurrentMouseModePreset(); void calculateSpringPreset(); void calculateMouseSpeedPreset(); void calculateWheelSpeedPreset(); void updateWindowTitleAxisName(); void calculateExtraAccelrationStatus(); void calculateExtraAccelerationMultiplier(); void calculateStartAccelerationMultiplier(); void calculateMinAccelerationThreshold(); void calculateMaxAccelerationThreshold(); void calculateAccelExtraDuration(); void calculateReleaseSpringRadius(); void calculateExtraAccelerationCurve(); public slots: void changeMouseMode(int index); void changeMouseCurve(int index); void updateConfigHorizontalSpeed(int value); void updateConfigVerticalSpeed(int value); void updateSpringWidth(int value); void updateSpringHeight(int value); void updateSensitivity(double value); void updateAccelerationCurvePresetComboBox(); void updateWheelSpeedHorizontalSpeed(int value); void updateWheelSpeedVerticalSpeed(int value); void updateSpringRelativeStatus(bool value); private slots: void updateExtraAccelerationCurve(int index); private: MouseAxisSettingsDialogHelper &getHelperLocal(); JoyAxis *axis; SpringModeRegionPreview *springPreviewWidget; MouseAxisSettingsDialogHelper helper; }; #endif // MOUSEAXISSETTINGSDIALOG_H AntiMicroX-antimicrox-b300273/src/mousedialog/mousebuttonsettingsdialog.cpp000066400000000000000000000263721471077622000273140ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mousebuttonsettingsdialog.h" #include "common.h" #include "inputdevice.h" #include "joybuttontypes/joybutton.h" #include "setjoystick.h" #include "springmoderegionpreview.h" #include #include #include #include #include MouseButtonSettingsDialog::MouseButtonSettingsDialog(JoyButton *button, QWidget *parent) : MouseSettingsDialog(parent) , helper(button) { setAttribute(Qt::WA_DeleteOnClose); resize(size().width(), 450); this->button = button; getHelperLocal().moveToThread(button->thread()); calculateMouseSpeedPreset(); selectCurrentMouseModePreset(); calculateSpringPreset(); if (button->getSensitivity() > 0.0) { ui->sensitivityDoubleSpinBox->setValue(button->getSensitivity()); } updateAccelerationCurvePresetComboBox(); updateWindowTitleButtonName(); if (ui->mouseModeComboBox->currentIndex() == 2) { springPreviewWidget = new SpringModeRegionPreview(ui->springWidthSpinBox->value(), ui->springHeightSpinBox->value()); } else { springPreviewWidget = new SpringModeRegionPreview(0, 0); } ui->wheelHoriSpeedSpinBox->setValue(button->getWheelSpeedX()); ui->wheelVertSpeedSpinBox->setValue(button->getWheelSpeedY()); if (button->isRelativeSpring()) { ui->relativeSpringCheckBox->setChecked(true); } double easingDuration = button->getEasingDuration(); ui->easingDoubleSpinBox->setValue(easingDuration); if (button->isPartRealAxis()) { ui->extraAccelerationGroupBox->setChecked(button->isExtraAccelerationEnabled()); ui->extraAccelDoubleSpinBox->setValue(button->getExtraAccelerationMultiplier()); ui->minMultiDoubleSpinBox->setValue(button->getStartAccelMultiplier()); ui->minThresholdDoubleSpinBox->setValue(button->getMinAccelThreshold()); ui->maxThresholdDoubleSpinBox->setValue(button->getMaxAccelThreshold()); ui->accelExtraDurationDoubleSpinBox->setValue(button->getAccelExtraDuration()); } else { ui->extraAccelerationGroupBox->setVisible(false); } ui->releaseSpringRadiusspinBox->setValue(button->getSpringDeadCircleMultiplier()); calculateExtraAccelerationCurve(); changeSpringSectionStatus(ui->mouseModeComboBox->currentIndex()); changeSettingsWidgetStatus(ui->accelerationComboBox->currentIndex()); connect(this, &MouseButtonSettingsDialog::finished, springPreviewWidget, &SpringModeRegionPreview::deleteLater); connect(ui->mouseModeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseButtonSettingsDialog::changeMouseMode); connect(ui->accelerationComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseButtonSettingsDialog::changeMouseCurve); connect(ui->horizontalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseButtonSettingsDialog::updateConfigHorizontalSpeed); connect(ui->verticalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseButtonSettingsDialog::updateConfigVerticalSpeed); connect(ui->springWidthSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseButtonSettingsDialog::updateSpringWidth); connect(ui->springWidthSpinBox, static_cast(&QSpinBox::valueChanged), springPreviewWidget, &SpringModeRegionPreview::setSpringWidth); connect(ui->springHeightSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseButtonSettingsDialog::updateSpringHeight); connect(ui->springHeightSpinBox, static_cast(&QSpinBox::valueChanged), springPreviewWidget, &SpringModeRegionPreview::setSpringHeight); connect(ui->relativeSpringCheckBox, &QCheckBox::clicked, &helper, &MouseButtonSettingsDialogHelper::updateSpringRelativeStatus); connect(ui->sensitivityDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &MouseButtonSettingsDialog::updateSensitivity); QChar x = 'X'; QChar y = 'Y'; connect(ui->wheelHoriSpeedSpinBox, static_cast(&QSpinBox::valueChanged), button, [button, x](int value) { button->setWheelSpeed(value, x); }); connect(ui->wheelVertSpeedSpinBox, static_cast(&QSpinBox::valueChanged), button, [button, y](int value) { button->setWheelSpeed(value, y); }); connect(ui->easingDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), button, &JoyButton::setEasingDuration); connect(ui->extraAccelerationGroupBox, &QGroupBox::clicked, &helper, &MouseButtonSettingsDialogHelper::updateExtraAccelerationStatus); connect(ui->extraAccelDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseButtonSettingsDialogHelper::updateExtraAccelerationMultiplier); connect(ui->minMultiDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseButtonSettingsDialogHelper::updateStartMultiPercentage); connect(ui->minThresholdDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseButtonSettingsDialogHelper::updateMinAccelThreshold); connect(ui->maxThresholdDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseButtonSettingsDialogHelper::updateMaxAccelThreshold); connect(ui->accelExtraDurationDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseButtonSettingsDialogHelper::updateAccelExtraDuration); connect(ui->releaseSpringRadiusspinBox, static_cast(&QSpinBox::valueChanged), &helper, &MouseButtonSettingsDialogHelper::updateReleaseSpringRadius); connect(ui->extraAccelCurveComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseButtonSettingsDialog::updateExtraAccelerationCurve); } void MouseButtonSettingsDialog::changeMouseMode(int index) { if (index == 1) { button->setMouseMode(JoyButton::MouseCursor); if (springPreviewWidget->isVisible()) { springPreviewWidget->hide(); } } else if (index == 2) { button->setMouseMode(JoyButton::MouseSpring); if (!springPreviewWidget->isVisible()) { springPreviewWidget->setSpringWidth(ui->springWidthSpinBox->value()); springPreviewWidget->setSpringHeight(ui->springHeightSpinBox->value()); } if (button->isPartRealAxis()) { button->setExtraAccelerationStatus(false); } } } void MouseButtonSettingsDialog::changeMouseCurve(int index) { JoyButton::JoyMouseCurve temp = MouseSettingsDialog::getMouseCurveForIndex(index); button->setMouseCurve(temp); } void MouseButtonSettingsDialog::updateConfigHorizontalSpeed(int value) { QMetaObject::invokeMethod(button, "setMouseSpeedX", Q_ARG(int, value)); } void MouseButtonSettingsDialog::updateConfigVerticalSpeed(int value) { QMetaObject::invokeMethod(button, "setMouseSpeedY", Q_ARG(int, value)); } void MouseButtonSettingsDialog::updateSpringWidth(int value) { QMetaObject::invokeMethod(button, "setSpringWidth", Q_ARG(int, value)); } void MouseButtonSettingsDialog::updateSpringHeight(int value) { QMetaObject::invokeMethod(button, "setSpringHeight", Q_ARG(int, value)); } void MouseButtonSettingsDialog::selectCurrentMouseModePreset() { JoyButton::JoyMouseMovementMode mode = button->getMouseMode(); if (mode == JoyButton::MouseCursor) { ui->mouseModeComboBox->setCurrentIndex(1); } else if (mode == JoyButton::MouseSpring) { ui->mouseModeComboBox->setCurrentIndex(2); } } void MouseButtonSettingsDialog::calculateSpringPreset() { int tempWidth = button->getSpringWidth(); int tempHeight = button->getSpringHeight(); if (tempWidth > 0) { ui->springWidthSpinBox->setValue(tempWidth); } if (tempHeight > 0) { ui->springHeightSpinBox->setValue(tempHeight); } } void MouseButtonSettingsDialog::calculateMouseSpeedPreset() { int tempMouseSpeedX = button->getMouseSpeedX(); int tempMouseSpeedY = button->getMouseSpeedY(); ui->horizontalSpinBox->setValue(tempMouseSpeedX); ui->verticalSpinBox->setValue(tempMouseSpeedY); } void MouseButtonSettingsDialog::updateSensitivity(double value) { button->setSensitivity(value); } void MouseButtonSettingsDialog::updateAccelerationCurvePresetComboBox() { JoyButton::JoyMouseCurve temp = button->getMouseCurve(); MouseSettingsDialog::updateAccelerationCurvePresetComboBox(temp); } void MouseButtonSettingsDialog::updateWindowTitleButtonName() { QString temp = QString(); temp.append(tr("Mouse Settings - ")).append(button->getPartialName(false, true)); if (button->getParentSet()->getIndex() != 0) { int setIndex = button->getParentSet()->getRealIndex(); temp.append(" [").append(tr("Set %1").arg(setIndex)); QString setName = button->getParentSet()->getName(); if (!setName.isEmpty()) { temp.append(": ").append(setName); } temp.append("]"); } setWindowTitle(temp); } void MouseButtonSettingsDialog::calculateExtraAccelerationCurve() { JoyButton::JoyExtraAccelerationCurve temp = button->getExtraAccelerationCurve(); updateExtraAccelerationCurvePresetComboBox(temp); } void MouseButtonSettingsDialog::updateExtraAccelerationCurve(int index) { JoyButton::JoyExtraAccelerationCurve temp = getExtraAccelCurveForIndex(index); if (index > 0) { PadderCommon::inputDaemonMutex.lock(); button->setExtraAccelerationCurve(temp); button->setExtraAccelerationCurve(temp); PadderCommon::inputDaemonMutex.unlock(); } } JoyButton *MouseButtonSettingsDialog::getButton() const { return button; } SpringModeRegionPreview *MouseButtonSettingsDialog::getSpringPreviewWidget() const { return springPreviewWidget; } MouseButtonSettingsDialogHelper const &MouseButtonSettingsDialog::getHelper() { return helper; } MouseButtonSettingsDialogHelper &MouseButtonSettingsDialog::getHelperLocal() { return helper; } AntiMicroX-antimicrox-b300273/src/mousedialog/mousebuttonsettingsdialog.h000066400000000000000000000043221471077622000267500ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MOUSEBUTTONSETTINGSDIALOG_H #define MOUSEBUTTONSETTINGSDIALOG_H #include "ui_mousesettingsdialog.h" #include "mousesettingsdialog.h" #include "uihelpers/mousebuttonsettingsdialoghelper.h" class JoyButton; class SpringModeRegionPreview; class MouseButtonSettingsDialog : public MouseSettingsDialog { Q_OBJECT public: explicit MouseButtonSettingsDialog(JoyButton *button, QWidget *parent = nullptr); JoyButton *getButton() const; SpringModeRegionPreview *getSpringPreviewWidget() const; MouseButtonSettingsDialogHelper const &getHelper(); protected: void selectCurrentMouseModePreset(); void calculateSpringPreset(); void calculateMouseSpeedPreset(); void updateWindowTitleButtonName(); void calculateExtraAccelerationCurve(); public slots: void changeMouseMode(int index); void changeMouseCurve(int index); void updateConfigHorizontalSpeed(int value); void updateConfigVerticalSpeed(int value); void updateSpringWidth(int value); void updateSpringHeight(int value); void updateSensitivity(double value); void updateAccelerationCurvePresetComboBox(); private slots: void updateExtraAccelerationCurve(int index); private: MouseButtonSettingsDialogHelper &getHelperLocal(); JoyButton *button; SpringModeRegionPreview *springPreviewWidget; MouseButtonSettingsDialogHelper helper; }; #endif // MOUSEBUTTONSETTINGSDIALOG_H AntiMicroX-antimicrox-b300273/src/mousedialog/mousecontrolsticksettingsdialog.cpp000066400000000000000000000340631471077622000305130ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mousecontrolsticksettingsdialog.h" #include "common.h" #include "inputdevice.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joycontrolstick.h" #include "setjoystick.h" #include "springmoderegionpreview.h" #include #include #include #include MouseControlStickSettingsDialog::MouseControlStickSettingsDialog(JoyControlStick *stick, QWidget *parent) : MouseSettingsDialog(parent) , helper(stick) { setAttribute(Qt::WA_DeleteOnClose); this->stick = stick; getHelperLocal().moveToThread(stick->thread()); calculateMouseSpeedPreset(); selectCurrentMouseModePreset(); calculateSpringPreset(); if (stick->getButtonsPresetSensitivity() > 0.0) { ui->sensitivityDoubleSpinBox->setValue(stick->getButtonsPresetSensitivity()); } updateAccelerationCurvePresetComboBox(); updateWindowTitleStickName(); if (ui->mouseModeComboBox->currentIndex() == 2) { springPreviewWidget = new SpringModeRegionPreview(ui->springWidthSpinBox->value(), ui->springHeightSpinBox->value()); } else { springPreviewWidget = new SpringModeRegionPreview(0, 0); } calculateWheelSpeedPreset(); if (stick->isRelativeSpring()) { ui->relativeSpringCheckBox->setChecked(true); } double easingDuration = stick->getButtonsEasingDuration(); ui->easingDoubleSpinBox->setValue(easingDuration); calculateExtraAccelrationStatus(); calculateExtraAccelerationMultiplier(); calculateStartAccelerationMultiplier(); calculateMinAccelerationThreshold(); calculateMaxAccelerationThreshold(); calculateAccelExtraDuration(); calculateReleaseSpringRadius(); calculateExtraAccelerationCurve(); changeSpringSectionStatus(ui->mouseModeComboBox->currentIndex()); changeSettingsWidgetStatus(ui->accelerationComboBox->currentIndex()); connect(this, &MouseControlStickSettingsDialog::finished, springPreviewWidget, &SpringModeRegionPreview::deleteLater); connect(ui->mouseModeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseControlStickSettingsDialog::changeMouseMode); connect(ui->accelerationComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseControlStickSettingsDialog::changeMouseCurve); connect(ui->horizontalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseControlStickSettingsDialog::updateConfigHorizontalSpeed); connect(ui->verticalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseControlStickSettingsDialog::updateConfigVerticalSpeed); connect(ui->springWidthSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseControlStickSettingsDialog::updateSpringWidth); connect(ui->springWidthSpinBox, static_cast(&QSpinBox::valueChanged), springPreviewWidget, &SpringModeRegionPreview::setSpringWidth); connect(ui->springHeightSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseControlStickSettingsDialog::updateSpringHeight); connect(ui->springHeightSpinBox, static_cast(&QSpinBox::valueChanged), springPreviewWidget, &SpringModeRegionPreview::setSpringHeight); connect(ui->relativeSpringCheckBox, &QCheckBox::clicked, this, &MouseControlStickSettingsDialog::updateSpringRelativeStatus); connect(ui->sensitivityDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &MouseControlStickSettingsDialog::updateSensitivity); connect(ui->wheelHoriSpeedSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseControlStickSettingsDialog::updateWheelSpeedHorizontalSpeed); connect(ui->wheelVertSpeedSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseControlStickSettingsDialog::updateWheelSpeedVerticalSpeed); connect(ui->easingDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), stick, &JoyControlStick::setButtonsEasingDuration); connect(ui->extraAccelerationGroupBox, &QGroupBox::clicked, &helper, &MouseControlStickSettingsDialogHelper::updateExtraAccelerationStatus); connect(ui->extraAccelDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseControlStickSettingsDialogHelper::updateExtraAccelerationMultiplier); connect(ui->minMultiDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseControlStickSettingsDialogHelper::updateStartMultiPercentage); connect(ui->minThresholdDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseControlStickSettingsDialogHelper::updateMinAccelThreshold); connect(ui->maxThresholdDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseControlStickSettingsDialogHelper::updateMaxAccelThreshold); connect(ui->accelExtraDurationDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), &helper, &MouseControlStickSettingsDialogHelper::updateAccelExtraDuration); connect(ui->releaseSpringRadiusspinBox, static_cast(&QSpinBox::valueChanged), &helper, &MouseControlStickSettingsDialogHelper::updateReleaseSpringRadius); connect(ui->extraAccelCurveComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseControlStickSettingsDialog::updateExtraAccelerationCurve); } void MouseControlStickSettingsDialog::changeMouseMode(int index) { if (index == 1) { stick->setButtonsMouseMode(JoyButton::MouseCursor); if (springPreviewWidget->isVisible()) { springPreviewWidget->hide(); } } else if (index == 2) { stick->setButtonsMouseMode(JoyButton::MouseSpring); if (!springPreviewWidget->isVisible()) { springPreviewWidget->setSpringWidth(ui->springWidthSpinBox->value()); springPreviewWidget->setSpringHeight(ui->springHeightSpinBox->value()); } stick->setButtonsExtraAccelerationStatus(false); } } void MouseControlStickSettingsDialog::changeMouseCurve(int index) { JoyButton::JoyMouseCurve temp = MouseSettingsDialog::getMouseCurveForIndex(index); stick->setButtonsMouseCurve(temp); } void MouseControlStickSettingsDialog::updateConfigHorizontalSpeed(int value) { QHashIterator iter(*stick->getButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setMouseSpeedX(value); } } void MouseControlStickSettingsDialog::updateConfigVerticalSpeed(int value) { QHashIterator iter(*stick->getButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); button->setMouseSpeedY(value); } } void MouseControlStickSettingsDialog::updateSpringWidth(int value) { stick->setButtonsSpringWidth(value); } void MouseControlStickSettingsDialog::updateSpringHeight(int value) { stick->setButtonsSpringHeight(value); } void MouseControlStickSettingsDialog::selectCurrentMouseModePreset() { bool presetDefined = stick->hasSameButtonsMouseMode(); if (presetDefined) { JoyButton::JoyMouseMovementMode mode = stick->getButtonsPresetMouseMode(); if (mode == JoyButton::MouseCursor) { ui->mouseModeComboBox->setCurrentIndex(1); } else if (mode == JoyButton::MouseSpring) { ui->mouseModeComboBox->setCurrentIndex(2); } } else { ui->mouseModeComboBox->setCurrentIndex(0); } } void MouseControlStickSettingsDialog::calculateSpringPreset() { int tempWidth = stick->getButtonsPresetSpringWidth(); int tempHeight = stick->getButtonsPresetSpringHeight(); if (tempWidth > 0) { ui->springWidthSpinBox->setValue(tempWidth); } if (tempHeight > 0) { ui->springHeightSpinBox->setValue(tempHeight); } } void MouseControlStickSettingsDialog::calculateMouseSpeedPreset() { QHashIterator iter(*stick->getButtons()); int tempMouseSpeedX = 0; while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); tempMouseSpeedX = qMax(tempMouseSpeedX, button->getMouseSpeedX()); } iter.toFront(); int tempMouseSpeedY = 0; while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); tempMouseSpeedY = qMax(tempMouseSpeedY, button->getMouseSpeedY()); } ui->horizontalSpinBox->setValue(tempMouseSpeedX); ui->verticalSpinBox->setValue(tempMouseSpeedY); } void MouseControlStickSettingsDialog::updateSensitivity(double value) { stick->setButtonsSensitivity(value); } void MouseControlStickSettingsDialog::updateAccelerationCurvePresetComboBox() { JoyButton::JoyMouseCurve temp = stick->getButtonsPresetMouseCurve(); MouseSettingsDialog::updateAccelerationCurvePresetComboBox(temp); } void MouseControlStickSettingsDialog::calculateWheelSpeedPreset() { QHashIterator iter(*stick->getButtons()); int tempWheelSpeedX = 0; int tempWheelSpeedY = 0; while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); tempWheelSpeedX = qMax(tempWheelSpeedX, button->getWheelSpeedX()); tempWheelSpeedY = qMax(tempWheelSpeedY, button->getWheelSpeedY()); } ui->wheelHoriSpeedSpinBox->setValue(tempWheelSpeedX); ui->wheelVertSpeedSpinBox->setValue(tempWheelSpeedY); } void MouseControlStickSettingsDialog::updateWheelSpeedHorizontalSpeed(int value) { stick->setButtonsWheelSpeedX(value); } void MouseControlStickSettingsDialog::updateWheelSpeedVerticalSpeed(int value) { stick->setButtonsWheelSpeedY(value); } void MouseControlStickSettingsDialog::updateSpringRelativeStatus(bool value) { stick->setButtonsSpringRelativeStatus(value); } void MouseControlStickSettingsDialog::updateWindowTitleStickName() { QString temp = QString(tr("Mouse Settings")).append(" - "); if (!stick->getStickName().isEmpty()) { temp.append(stick->getPartialName(false, true)); } else { temp.append(stick->getPartialName()); } if (stick->getParentSet()->getIndex() != 0) { int setIndex = stick->getParentSet()->getRealIndex(); temp.append(" [").append(tr("Set %1").arg(setIndex)); QString setName = stick->getParentSet()->getName(); if (!setName.isEmpty()) { temp.append(": ").append(setName); } temp.append("]"); } setWindowTitle(temp); } void MouseControlStickSettingsDialog::calculateExtraAccelrationStatus() { if (stick->getButtonsExtraAccelerationStatus()) { ui->extraAccelerationGroupBox->setChecked(true); } } void MouseControlStickSettingsDialog::calculateExtraAccelerationMultiplier() { ui->extraAccelDoubleSpinBox->setValue(stick->getButtonsExtraAccelerationMultiplier()); } void MouseControlStickSettingsDialog::calculateStartAccelerationMultiplier() { ui->minMultiDoubleSpinBox->setValue(stick->getButtonsStartAccelerationMultiplier()); } void MouseControlStickSettingsDialog::calculateMinAccelerationThreshold() { ui->minThresholdDoubleSpinBox->setValue(stick->getButtonsMinAccelerationThreshold()); } void MouseControlStickSettingsDialog::calculateMaxAccelerationThreshold() { ui->maxThresholdDoubleSpinBox->setValue(stick->getButtonsMaxAccelerationThreshold()); } void MouseControlStickSettingsDialog::calculateAccelExtraDuration() { ui->accelExtraDurationDoubleSpinBox->setValue(stick->getButtonsAccelerationEasingDuration()); } void MouseControlStickSettingsDialog::calculateReleaseSpringRadius() { ui->releaseSpringRadiusspinBox->setValue(stick->getButtonsSpringDeadCircleMultiplier()); } void MouseControlStickSettingsDialog::calculateExtraAccelerationCurve() { JoyButton::JoyExtraAccelerationCurve curve = stick->getButtonsExtraAccelerationCurve(); updateExtraAccelerationCurvePresetComboBox(curve); } void MouseControlStickSettingsDialog::updateExtraAccelerationCurve(int index) { JoyButton::JoyExtraAccelerationCurve temp = getExtraAccelCurveForIndex(index); if (index > 0) { PadderCommon::inputDaemonMutex.lock(); stick->setButtonsExtraAccelCurve(temp); PadderCommon::inputDaemonMutex.unlock(); } } JoyControlStick *MouseControlStickSettingsDialog::getStick() const { return stick; } SpringModeRegionPreview *MouseControlStickSettingsDialog::getSpringPreviewWidget() const { return springPreviewWidget; } MouseControlStickSettingsDialogHelper const &MouseControlStickSettingsDialog::getHelper() { return helper; } MouseControlStickSettingsDialogHelper &MouseControlStickSettingsDialog::getHelperLocal() { return helper; } AntiMicroX-antimicrox-b300273/src/mousedialog/mousecontrolsticksettingsdialog.h000066400000000000000000000054231471077622000301560ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MOUSECONTROLSTICKSETTINGSDIALOG_H #define MOUSECONTROLSTICKSETTINGSDIALOG_H #include "ui_mousesettingsdialog.h" #include "mousesettingsdialog.h" #include "uihelpers/mousecontrolsticksettingsdialoghelper.h" class JoyControlStick; class SpringModeRegionPreview; class MouseControlStickSettingsDialog : public MouseSettingsDialog { Q_OBJECT public: explicit MouseControlStickSettingsDialog(JoyControlStick *stick, QWidget *parent = 0); JoyControlStick *getStick() const; SpringModeRegionPreview *getSpringPreviewWidget() const; MouseControlStickSettingsDialogHelper const &getHelper(); protected: void selectCurrentMouseModePreset(); void calculateSpringPreset(); void calculateMouseSpeedPreset(); void calculateWheelSpeedPreset(); void updateWindowTitleStickName(); void calculateExtraAccelrationStatus(); void calculateExtraAccelerationMultiplier(); void calculateStartAccelerationMultiplier(); void calculateMinAccelerationThreshold(); void calculateMaxAccelerationThreshold(); void calculateAccelExtraDuration(); void calculateReleaseSpringRadius(); void calculateExtraAccelerationCurve(); public slots: void changeMouseMode(int index); void changeMouseCurve(int index); void updateConfigHorizontalSpeed(int value); void updateConfigVerticalSpeed(int value); void updateSpringWidth(int value); void updateSpringHeight(int value); void updateSensitivity(double value); void updateAccelerationCurvePresetComboBox(); void updateWheelSpeedHorizontalSpeed(int value); void updateWheelSpeedVerticalSpeed(int value); void updateSpringRelativeStatus(bool value); private slots: void updateExtraAccelerationCurve(int index); private: MouseControlStickSettingsDialogHelper &getHelperLocal(); JoyControlStick *stick; SpringModeRegionPreview *springPreviewWidget; MouseControlStickSettingsDialogHelper helper; }; #endif // MOUSECONTROLSTICKSETTINGSDIALOG_H AntiMicroX-antimicrox-b300273/src/mousedialog/mousedpadsettingsdialog.cpp000066400000000000000000000271601471077622000267050ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mousedpadsettingsdialog.h" #include "joydpad.h" #include "springmoderegionpreview.h" #include "common.h" #include "inputdevice.h" #include "setjoystick.h" #include #include #include MouseDPadSettingsDialog::MouseDPadSettingsDialog(JoyDPad *dpad, QWidget *parent) : MouseSettingsDialog(parent) , helper(dpad) { setAttribute(Qt::WA_DeleteOnClose); resize(size().width(), 450); this->dpad = dpad; helper.moveToThread(dpad->thread()); calculateMouseSpeedPreset(); selectCurrentMouseModePreset(); calculateSpringPreset(); if (dpad->getButtonsPresetSensitivity() > 0.0) { ui->sensitivityDoubleSpinBox->setValue(dpad->getButtonsPresetSensitivity()); } updateAccelerationCurvePresetComboBox(); updateWindowTitleDPadName(); if (ui->mouseModeComboBox->currentIndex() == 2) { springPreviewWidget = new SpringModeRegionPreview(ui->springWidthSpinBox->value(), ui->springHeightSpinBox->value()); } else { springPreviewWidget = new SpringModeRegionPreview(0, 0); } calculateWheelSpeedPreset(); if (dpad->isRelativeSpring()) { ui->relativeSpringCheckBox->setChecked(true); } double easingDuration = dpad->getButtonsEasingDuration(); ui->easingDoubleSpinBox->setValue(easingDuration); ui->extraAccelerationGroupBox->setVisible(false); calculateReleaseSpringRadius(); calculateExtraAccelerationCurve(); changeSpringSectionStatus(ui->mouseModeComboBox->currentIndex()); changeSettingsWidgetStatus(ui->accelerationComboBox->currentIndex()); connect(this, &MouseDPadSettingsDialog::finished, springPreviewWidget, &SpringModeRegionPreview::deleteLater); connect(ui->mouseModeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseDPadSettingsDialog::changeMouseMode); connect(ui->accelerationComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseDPadSettingsDialog::changeMouseCurve); connect(ui->horizontalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseDPadSettingsDialog::updateConfigHorizontalSpeed); connect(ui->verticalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseDPadSettingsDialog::updateConfigVerticalSpeed); connect(ui->springWidthSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseDPadSettingsDialog::updateSpringWidth); connect(ui->springWidthSpinBox, static_cast(&QSpinBox::valueChanged), springPreviewWidget, &SpringModeRegionPreview::setSpringWidth); connect(ui->springHeightSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseDPadSettingsDialog::updateSpringHeight); connect(ui->springHeightSpinBox, static_cast(&QSpinBox::valueChanged), springPreviewWidget, &SpringModeRegionPreview::setSpringHeight); connect(ui->relativeSpringCheckBox, &QCheckBox::clicked, this, &MouseDPadSettingsDialog::updateSpringRelativeStatus); connect(ui->sensitivityDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), this, &MouseDPadSettingsDialog::updateSensitivity); connect(ui->wheelHoriSpeedSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseDPadSettingsDialog::updateWheelSpeedHorizontalSpeed); connect(ui->wheelVertSpeedSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseDPadSettingsDialog::updateWheelSpeedVerticalSpeed); connect(ui->easingDoubleSpinBox, static_cast(&QDoubleSpinBox::valueChanged), dpad, &JoyDPad::setButtonsEasingDuration); connect(ui->releaseSpringRadiusspinBox, static_cast(&QSpinBox::valueChanged), this, &MouseDPadSettingsDialog::updateReleaseSpringRadius); connect(ui->extraAccelCurveComboBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseDPadSettingsDialog::updateExtraAccelerationCurve); JoyButtonMouseHelper *mouseHelper = JoyButton::getMouseHelper(); connect(mouseHelper, &JoyButtonMouseHelper::mouseCursorMoved, this, &MouseDPadSettingsDialog::updateMouseCursorStatusLabels); connect(mouseHelper, &JoyButtonMouseHelper::mouseSpringMoved, this, &MouseDPadSettingsDialog::updateMouseSpringStatusLabels); lastMouseStatUpdate.start(); } void MouseDPadSettingsDialog::changeMouseMode(int index) { if (index == 1) { dpad->setButtonsMouseMode(JoyButton::MouseCursor); if (springPreviewWidget->isVisible()) { springPreviewWidget->hide(); } } else if (index == 2) { dpad->setButtonsMouseMode(JoyButton::MouseSpring); if (!springPreviewWidget->isVisible()) { springPreviewWidget->setSpringWidth(ui->springWidthSpinBox->value()); springPreviewWidget->setSpringHeight(ui->springHeightSpinBox->value()); } } } void MouseDPadSettingsDialog::changeMouseCurve(int index) { JoyButton::JoyMouseCurve temp = MouseSettingsDialog::getMouseCurveForIndex(index); dpad->setButtonsMouseCurve(temp); } void MouseDPadSettingsDialog::updateConfigHorizontalSpeed(int value) { QHashIterator iter(*dpad->getButtons()); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setMouseSpeedX(value); } } void MouseDPadSettingsDialog::updateConfigVerticalSpeed(int value) { QHashIterator iter(*dpad->getButtons()); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->setMouseSpeedY(value); } } void MouseDPadSettingsDialog::updateSpringWidth(int value) { dpad->setButtonsSpringWidth(value); } void MouseDPadSettingsDialog::updateSpringHeight(int value) { dpad->setButtonsSpringHeight(value); } void MouseDPadSettingsDialog::selectCurrentMouseModePreset() { bool presetDefined = dpad->hasSameButtonsMouseMode(); if (presetDefined) { JoyButton::JoyMouseMovementMode mode = dpad->getButtonsPresetMouseMode(); if (mode == JoyButton::MouseCursor) { ui->mouseModeComboBox->setCurrentIndex(1); } else if (mode == JoyButton::MouseSpring) { ui->mouseModeComboBox->setCurrentIndex(2); } } else { ui->mouseModeComboBox->setCurrentIndex(0); } } void MouseDPadSettingsDialog::calculateSpringPreset() { int tempWidth = dpad->getButtonsPresetSpringWidth(); int tempHeight = dpad->getButtonsPresetSpringHeight(); if (tempWidth > 0) { ui->springWidthSpinBox->setValue(tempWidth); } if (tempHeight > 0) { ui->springHeightSpinBox->setValue(tempHeight); } } void MouseDPadSettingsDialog::calculateMouseSpeedPreset() { QHashIterator iter(*dpad->getButtons()); int tempMouseSpeedX = 0; while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); tempMouseSpeedX = qMax(tempMouseSpeedX, button->getMouseSpeedX()); } iter.toFront(); int tempMouseSpeedY = 0; while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); tempMouseSpeedY = qMax(tempMouseSpeedY, button->getMouseSpeedY()); } ui->horizontalSpinBox->setValue(tempMouseSpeedX); ui->verticalSpinBox->setValue(tempMouseSpeedY); } void MouseDPadSettingsDialog::updateSensitivity(double value) { dpad->setButtonsSensitivity(value); } void MouseDPadSettingsDialog::updateAccelerationCurvePresetComboBox() { JoyButton::JoyMouseCurve temp = dpad->getButtonsPresetMouseCurve(); MouseSettingsDialog::updateAccelerationCurvePresetComboBox(temp); } void MouseDPadSettingsDialog::calculateWheelSpeedPreset() { QHashIterator iter(*dpad->getButtons()); int tempWheelSpeedX = 0; int tempWheelSpeedY = 0; while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); tempWheelSpeedX = qMax(tempWheelSpeedX, button->getWheelSpeedX()); tempWheelSpeedY = qMax(tempWheelSpeedY, button->getWheelSpeedY()); } ui->wheelHoriSpeedSpinBox->setValue(tempWheelSpeedX); ui->wheelVertSpeedSpinBox->setValue(tempWheelSpeedY); } void MouseDPadSettingsDialog::updateWheelSpeedHorizontalSpeed(int value) { dpad->setButtonsWheelSpeedX(value); } void MouseDPadSettingsDialog::updateWheelSpeedVerticalSpeed(int value) { dpad->setButtonsWheelSpeedY(value); } void MouseDPadSettingsDialog::updateSpringRelativeStatus(bool value) { dpad->setButtonsSpringRelativeStatus(value); } void MouseDPadSettingsDialog::updateWindowTitleDPadName() { QString temp = QString(tr("Mouse Settings")).append(" - "); if (!dpad->getDpadName().isEmpty()) { temp.append(dpad->getName(false, true)); } else { temp.append(dpad->getName()); } if (dpad->getParentSet()->getIndex() != 0) { int setIndex = dpad->getParentSet()->getRealIndex(); temp.append(" [").append(tr("Set %1").arg(setIndex)); QString setName = dpad->getParentSet()->getName(); if (!setName.isEmpty()) { temp.append(": ").append(setName); } temp.append("]"); } setWindowTitle(temp); } void MouseDPadSettingsDialog::updateReleaseSpringRadius(int value) { dpad->setButtonsSpringDeadCircleMultiplier(value); } void MouseDPadSettingsDialog::calculateReleaseSpringRadius() { ui->releaseSpringRadiusspinBox->setValue(dpad->getButtonsSpringDeadCircleMultiplier()); } void MouseDPadSettingsDialog::calculateExtraAccelerationCurve() { JoyButton::JoyExtraAccelerationCurve curve = dpad->getButtonsExtraAccelerationCurve(); updateExtraAccelerationCurvePresetComboBox(curve); } void MouseDPadSettingsDialog::updateExtraAccelerationCurve(int index) { JoyButton::JoyExtraAccelerationCurve temp = JoyButton::LinearAccelCurve; if (index > 0) { InputDevice *device = dpad->getParentSet()->getInputDevice(); PadderCommon::lockInputDevices(); QMetaObject::invokeMethod(device, "haltServices", Qt::BlockingQueuedConnection); temp = getExtraAccelCurveForIndex(index); dpad->setButtonsExtraAccelerationCurve(temp); PadderCommon::unlockInputDevices(); } } JoyDPad *MouseDPadSettingsDialog::getDPad() const { return dpad; } SpringModeRegionPreview *MouseDPadSettingsDialog::getSpringPreviewWidget() const { return springPreviewWidget; } MouseDpadSettingsDialogHelper const &MouseDPadSettingsDialog::getHelper() { return helper; } MouseDpadSettingsDialogHelper &MouseDPadSettingsDialog::getHelperLocal() { return helper; } AntiMicroX-antimicrox-b300273/src/mousedialog/mousedpadsettingsdialog.h000066400000000000000000000047071471077622000263540ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MOUSEDPADSETTINGSDIALOG_H #define MOUSEDPADSETTINGSDIALOG_H #include "ui_mousesettingsdialog.h" #include "mousesettingsdialog.h" #include "uihelpers/mousedpadsettingsdialoghelper.h" class JoyDPad; class SpringModeRegionPreview; class MouseDPadSettingsDialog : public MouseSettingsDialog { Q_OBJECT public: explicit MouseDPadSettingsDialog(JoyDPad *dpad, QWidget *parent = nullptr); JoyDPad *getDPad() const; SpringModeRegionPreview *getSpringPreviewWidget() const; MouseDpadSettingsDialogHelper const &getHelper(); protected: void selectCurrentMouseModePreset(); void calculateSpringPreset(); void calculateMouseSpeedPreset(); void calculateWheelSpeedPreset(); void updateWindowTitleDPadName(); void calculateReleaseSpringRadius(); void calculateExtraAccelerationCurve(); public slots: void changeMouseMode(int index); void changeMouseCurve(int index); void updateConfigHorizontalSpeed(int value); void updateConfigVerticalSpeed(int value); void updateSpringWidth(int value); void updateSpringHeight(int value); void updateSensitivity(double value); void updateAccelerationCurvePresetComboBox(); void updateWheelSpeedHorizontalSpeed(int value); void updateWheelSpeedVerticalSpeed(int value); void updateSpringRelativeStatus(bool value); private slots: void updateReleaseSpringRadius(int value); void updateExtraAccelerationCurve(int index); private: MouseDpadSettingsDialogHelper &getHelperLocal(); JoyDPad *dpad; SpringModeRegionPreview *springPreviewWidget; MouseDpadSettingsDialogHelper helper; }; #endif // MOUSEDPADSETTINGSDIALOG_H AntiMicroX-antimicrox-b300273/src/mousedialog/mousesensorsettingsdialog.cpp000066400000000000000000000151511471077622000273030ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mousesensorsettingsdialog.h" #include "common.h" #include "inputdevice.h" #include "joybuttontypes/joysensorbutton.h" #include "joysensor.h" #include "setjoystick.h" #include #include #include #include MouseSensorSettingsDialog::MouseSensorSettingsDialog(JoySensor *sensor, QWidget *parent) : MouseSettingsDialog(parent) , m_sensor(sensor) { setAttribute(Qt::WA_DeleteOnClose); ui->topGroupBox->setVisible(false); ui->springGroupBox->setVisible(false); ui->extraAccelerationGroupBox->setVisible(false); ui->sensLabel->setVisible(false); ui->sensitivityDoubleSpinBox->setVisible(false); ui->easingDurationLabel->setVisible(false); ui->easingDoubleSpinBox->setVisible(false); calculateMouseSpeedPreset(); updateWindowTitleSensorName(); calculateWheelSpeedPreset(); changeSettingsWidgetStatus(ui->accelerationComboBox->currentIndex()); connect(ui->horizontalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseSensorSettingsDialog::updateConfigHorizontalSpeed); connect(ui->verticalSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseSensorSettingsDialog::updateConfigVerticalSpeed); connect(ui->wheelHoriSpeedSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseSensorSettingsDialog::updateWheelSpeedHorizontalSpeed); connect(ui->wheelVertSpeedSpinBox, static_cast(&QSpinBox::valueChanged), this, &MouseSensorSettingsDialog::updateWheelSpeedVerticalSpeed); } /** * @brief Gets the underlying JoySensor object */ JoySensor *MouseSensorSettingsDialog::getSensor() const { return m_sensor; } /** * @brief Get the maximum mouse speed used by the buttons of the associated * sensor and set the UI values to it. */ void MouseSensorSettingsDialog::calculateMouseSpeedPreset() { auto buttons = m_sensor->getButtons(); int mouseSpeedX = 0; int mouseSpeedY = 0; for (auto iter = buttons->cbegin(); iter != buttons->cend(); ++iter) { JoySensorButton *button = iter.value(); mouseSpeedX = qMax(mouseSpeedX, button->getMouseSpeedX()); mouseSpeedY = qMax(mouseSpeedY, button->getMouseSpeedY()); } ui->horizontalSpinBox->setValue(mouseSpeedX); ui->verticalSpinBox->setValue(mouseSpeedY); } /** * @brief Get the maximum mouse wheel speed used by the buttons of the associated * sensor and set the UI values to it. */ void MouseSensorSettingsDialog::calculateWheelSpeedPreset() { auto buttons = m_sensor->getButtons(); int wheelSpeedX = 0; int wheelSpeedY = 0; for (auto iter = buttons->cbegin(); iter != buttons->cend(); ++iter) { JoySensorButton *button = iter.value(); wheelSpeedX = qMax(wheelSpeedX, button->getWheelSpeedX()); wheelSpeedY = qMax(wheelSpeedY, button->getWheelSpeedY()); } ui->wheelHoriSpeedSpinBox->setValue(wheelSpeedX); ui->wheelVertSpeedSpinBox->setValue(wheelSpeedY); } /** * @brief Shows the sensor name in dialog title */ void MouseSensorSettingsDialog::updateWindowTitleSensorName() { QString temp = QString(tr("Mouse Settings")).append(" - "); if (!m_sensor->getSensorName().isEmpty()) temp.append(m_sensor->getPartialName(false, true)); else temp.append(m_sensor->getPartialName()); if (m_sensor->getParentSet()->getIndex() != 0) { int setIndex = m_sensor->getParentSet()->getRealIndex(); temp.append(" [").append(tr("Set %1").arg(setIndex)); QString setName = m_sensor->getParentSet()->getName(); if (!setName.isEmpty()) temp.append(": ").append(setName); temp.append("]"); } setWindowTitle(temp); } /** * @brief Horizontal mouse speed change UI event handler * Updates horizontal mouse speed on all buttons of the associated sensor. */ void MouseSensorSettingsDialog::updateConfigHorizontalSpeed(int value) { auto buttons = m_sensor->getButtons(); for (auto iter = buttons->begin(); iter != buttons->end(); ++iter) { JoySensorButton *button = iter.value(); button->setMouseSpeedX(value); } } /** * @brief Vertical mouse speed change UI event handler * Updates vertical mouse speed on all buttons of the associated sensor. */ void MouseSensorSettingsDialog::updateConfigVerticalSpeed(int value) { auto buttons = m_sensor->getButtons(); for (auto iter = buttons->begin(); iter != buttons->end(); ++iter) { JoySensorButton *button = iter.value(); button->setMouseSpeedY(value); } } /** * @brief Horizontal mouse wheel speed change UI event handler * Updates horizontal mouse wheel speed on all buttons of the associated sensor. */ void MouseSensorSettingsDialog::updateWheelSpeedHorizontalSpeed(int value) { auto buttons = m_sensor->getButtons(); for (auto iter = buttons->begin(); iter != buttons->end(); ++iter) { JoySensorButton *button = iter.value(); button->setWheelSpeed(value, 'X'); } } /** * @brief Vertical mouse wheel speed change UI event handler * Updates vertical mouse wheel speed on all buttons of the associated sensor. */ void MouseSensorSettingsDialog::updateWheelSpeedVerticalSpeed(int value) { auto buttons = m_sensor->getButtons(); for (auto iter = buttons->begin(); iter != buttons->end(); ++iter) { JoySensorButton *button = iter.value(); button->setWheelSpeed(value, 'Y'); } } /** * @brief Not used for sensors but necessary to implement because it is an * abstract function in the parent class. */ void MouseSensorSettingsDialog::changeMouseMode(int index) { Q_UNUSED(index); } /** * @brief Not used for sensors but necessary to implement because it is an * abstract function in the parent class. */ void MouseSensorSettingsDialog::changeMouseCurve(int index) { Q_UNUSED(index); } AntiMicroX-antimicrox-b300273/src/mousedialog/mousesensorsettingsdialog.h000066400000000000000000000031331471077622000267450ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "ui_mousesettingsdialog.h" #include "mousesettingsdialog.h" class JoySensor; class SpringModeRegionPreview; /** * @brief Mouse settings dialog specialized for sensors */ class MouseSensorSettingsDialog : public MouseSettingsDialog { Q_OBJECT public: explicit MouseSensorSettingsDialog(JoySensor *sensor, QWidget *parent = 0); JoySensor *getSensor() const; protected: void calculateMouseSpeedPreset(); void calculateWheelSpeedPreset(); void updateWindowTitleSensorName(); public slots: void updateConfigHorizontalSpeed(int value); void updateConfigVerticalSpeed(int value); void updateWheelSpeedHorizontalSpeed(int value); void updateWheelSpeedVerticalSpeed(int value); virtual void changeMouseMode(int index); virtual void changeMouseCurve(int index); private: JoySensor *m_sensor; }; AntiMicroX-antimicrox-b300273/src/mousedialog/springmoderegionpreview.cpp000066400000000000000000000103471471077622000267370ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "springmoderegionpreview.h" #include #include #include #include #include SpringModeRegionPreview::SpringModeRegionPreview(int width, int height, QWidget *parent) : #if defined(Q_OS_WIN) QWidget(parent, Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint) #else QWidget(parent, Qt::FramelessWindowHint) #endif { int tempwidth = adjustSpringSizeWidth(width); int tempheight = adjustSpringSizeHeight(height); setAttribute(Qt::WA_NoSystemBackground); setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_ShowWithoutActivating); setWindowTitle(tr("Spring Mode Preview")); if ((tempwidth >= 2) && (tempheight >= 2)) { // TODO create a simple class representing display fopr calculating cursor locations int cw = (QGuiApplication::primaryScreen()->virtualGeometry().width() / 2) - (tempwidth / 2); int ch = (QGuiApplication::primaryScreen()->virtualGeometry().height() / 2) - (tempheight / 2); setGeometry(cw, ch, tempwidth, tempheight); show(); } else { resize(0, 0); move(0, 0); } } void SpringModeRegionPreview::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter p(this); QPen border; border.setWidth(3); border.setColor(Qt::black); p.setPen(border); p.drawRect(1, 1, width() - 3, height() - 3); } int SpringModeRegionPreview::adjustSpringSizeWidth(int width) { int tempwidth = size().width(); if (width >= 2) { tempwidth = width; } else { tempwidth = 0; } return tempwidth; } int SpringModeRegionPreview::adjustSpringSizeHeight(int height) { int tempheight; if (height >= 2) { tempheight = height; } else { tempheight = 0; } return tempheight; } void SpringModeRegionPreview::setSpringWidth(int width) { int tempwidth = adjustSpringSizeWidth(width); int height = size().height(); hide(); if ((tempwidth >= 2) && (height >= 2)) { int cw = (QGuiApplication::primaryScreen()->virtualGeometry().width() / 2) - (tempwidth / 2); int ch = (QGuiApplication::primaryScreen()->virtualGeometry().height() / 2) - (height / 2); setGeometry(cw, ch, tempwidth, height); if (!isVisible()) { show(); } } else { resize(tempwidth, height); move(0, 0); } } void SpringModeRegionPreview::setSpringHeight(int height) { int tempheight = adjustSpringSizeHeight(height); int width = size().width(); hide(); if ((width >= 2) && (tempheight >= 2)) { int cw = (QGuiApplication::primaryScreen()->virtualGeometry().width() / 2) - (width / 2); int ch = (QGuiApplication::primaryScreen()->virtualGeometry().height() / 2) - (tempheight / 2); setGeometry(cw, ch, width, tempheight); if (!isVisible()) { show(); } } else { resize(width, tempheight); move(0, 0); } } void SpringModeRegionPreview::setSpringSize(int width, int height) { int tempwidth = adjustSpringSizeWidth(width); int tempheight = adjustSpringSizeHeight(height); int cw = (QGuiApplication::primaryScreen()->virtualGeometry().width() / 2) - (tempwidth / 2); int ch = (QGuiApplication::primaryScreen()->virtualGeometry().height() / 2) - (height / 2); resize(tempwidth, tempheight); move(cw, ch); } AntiMicroX-antimicrox-b300273/src/mousedialog/springmoderegionpreview.h000066400000000000000000000026121471077622000264000ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SPRINGMODEREGIONPREVIEW_H #define SPRINGMODEREGIONPREVIEW_H #include class QPaintEvent; class SpringModeRegionPreview : public QWidget { Q_OBJECT public: explicit SpringModeRegionPreview(int width = 0, int height = 0, QWidget *parent = nullptr); protected: void paintEvent(QPaintEvent *event); int adjustSpringSizeWidth(int width); int adjustSpringSizeHeight(int height); public slots: void setSpringWidth(int width); void setSpringHeight(int height); void setSpringSize(int width, int height); }; #endif // SPRINGMODEREGIONPREVIEW_H AntiMicroX-antimicrox-b300273/src/mousedialog/uihelpers/000077500000000000000000000000001471077622000232515ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/mousedialog/uihelpers/mouseaxissettingsdialoghelper.cpp000066400000000000000000000050161471077622000321350ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mouseaxissettingsdialoghelper.h" #include "joyaxis.h" #include MouseAxisSettingsDialogHelper::MouseAxisSettingsDialogHelper(JoyAxis *axis, QObject *parent) : QObject(parent) { Q_ASSERT(axis); this->axis = axis; } void MouseAxisSettingsDialogHelper::updateExtraAccelerationStatus(bool checked) { axis->getPAxisButton()->setExtraAccelerationStatus(checked); axis->getNAxisButton()->setExtraAccelerationStatus(checked); } void MouseAxisSettingsDialogHelper::updateExtraAccelerationMultiplier(double value) { axis->getPAxisButton()->setExtraAccelerationMultiplier(value); axis->getNAxisButton()->setExtraAccelerationMultiplier(value); } void MouseAxisSettingsDialogHelper::updateStartMultiPercentage(double value) { axis->getPAxisButton()->setStartAccelMultiplier(value); axis->getNAxisButton()->setStartAccelMultiplier(value); } void MouseAxisSettingsDialogHelper::updateMinAccelThreshold(double value) { axis->getPAxisButton()->setMinAccelThreshold(value); axis->getNAxisButton()->setMinAccelThreshold(value); } void MouseAxisSettingsDialogHelper::updateMaxAccelThreshold(double value) { axis->getPAxisButton()->setMaxAccelThreshold(value); axis->getNAxisButton()->setMaxAccelThreshold(value); } void MouseAxisSettingsDialogHelper::updateAccelExtraDuration(double value) { axis->getPAxisButton()->setAccelExtraDuration(value); axis->getNAxisButton()->setAccelExtraDuration(value); } void MouseAxisSettingsDialogHelper::updateReleaseSpringRadius(int value) { axis->getPAxisButton()->setSpringDeadCircleMultiplier(value); axis->getNAxisButton()->setSpringDeadCircleMultiplier(value); } JoyAxis *MouseAxisSettingsDialogHelper::getAxis() const { return axis; } AntiMicroX-antimicrox-b300273/src/mousedialog/uihelpers/mouseaxissettingsdialoghelper.h000066400000000000000000000030571471077622000316050ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MOUSEAXISSETTINGSDIALOGHELPER_H #define MOUSEAXISSETTINGSDIALOGHELPER_H #include class JoyAxis; class MouseAxisSettingsDialogHelper : public QObject { Q_OBJECT public: explicit MouseAxisSettingsDialogHelper(JoyAxis *axis, QObject *parent = nullptr); JoyAxis *getAxis() const; public slots: void updateExtraAccelerationStatus(bool checked); void updateExtraAccelerationMultiplier(double value); void updateStartMultiPercentage(double value); void updateMinAccelThreshold(double value); void updateMaxAccelThreshold(double value); void updateAccelExtraDuration(double value); void updateReleaseSpringRadius(int value); private: JoyAxis *axis; }; #endif // MOUSEAXISSETTINGSDIALOGHELPER_H AntiMicroX-antimicrox-b300273/src/mousedialog/uihelpers/mousebuttonsettingsdialoghelper.cpp000066400000000000000000000042501471077622000325030ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mousebuttonsettingsdialoghelper.h" #include "joybuttonslot.h" #include "joybuttontypes/joybutton.h" #include MouseButtonSettingsDialogHelper::MouseButtonSettingsDialogHelper(JoyButton *button, QObject *parent) : QObject(parent) { Q_ASSERT(button); this->button = button; } void MouseButtonSettingsDialogHelper::updateExtraAccelerationStatus(bool checked) { button->setExtraAccelerationStatus(checked); } void MouseButtonSettingsDialogHelper::updateExtraAccelerationMultiplier(double value) { button->setExtraAccelerationMultiplier(value); } void MouseButtonSettingsDialogHelper::updateStartMultiPercentage(double value) { button->setStartAccelMultiplier(value); } void MouseButtonSettingsDialogHelper::updateMinAccelThreshold(double value) { button->setMinAccelThreshold(value); } void MouseButtonSettingsDialogHelper::updateMaxAccelThreshold(double value) { button->setMaxAccelThreshold(value); } void MouseButtonSettingsDialogHelper::updateAccelExtraDuration(double value) { button->setAccelExtraDuration(value); } void MouseButtonSettingsDialogHelper::updateReleaseSpringRadius(int value) { button->setSpringDeadCircleMultiplier(value); } void MouseButtonSettingsDialogHelper::updateSpringRelativeStatus(bool value) { button->setSpringRelativeStatus(value); } JoyButton *MouseButtonSettingsDialogHelper::getButton() const { return button; } AntiMicroX-antimicrox-b300273/src/mousedialog/uihelpers/mousebuttonsettingsdialoghelper.h000066400000000000000000000031671471077622000321560ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MOUSEBUTTONSETTINGSDIALOGHELPER_H #define MOUSEBUTTONSETTINGSDIALOGHELPER_H #include class JoyButton; class MouseButtonSettingsDialogHelper : public QObject { Q_OBJECT public: explicit MouseButtonSettingsDialogHelper(JoyButton *button, QObject *parent = nullptr); JoyButton *getButton() const; public slots: void updateExtraAccelerationStatus(bool checked); void updateExtraAccelerationMultiplier(double value); void updateStartMultiPercentage(double value); void updateMinAccelThreshold(double value); void updateMaxAccelThreshold(double value); void updateAccelExtraDuration(double value); void updateReleaseSpringRadius(int value); void updateSpringRelativeStatus(bool value); private: JoyButton *button; }; #endif // MOUSEBUTTONSETTINGSDIALOGHELPER_H AntiMicroX-antimicrox-b300273/src/mousedialog/uihelpers/mousecontrolsticksettingsdialoghelper.cpp000066400000000000000000000042541471077622000337120ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mousecontrolsticksettingsdialoghelper.h" #include "joycontrolstick.h" #include MouseControlStickSettingsDialogHelper::MouseControlStickSettingsDialogHelper(JoyControlStick *stick, QObject *parent) : QObject(parent) { Q_ASSERT(stick); this->stick = stick; } void MouseControlStickSettingsDialogHelper::updateExtraAccelerationStatus(bool checked) { stick->setButtonsExtraAccelerationStatus(checked); } void MouseControlStickSettingsDialogHelper::updateExtraAccelerationMultiplier(double value) { stick->setButtonsExtraAccelerationMultiplier(value); } void MouseControlStickSettingsDialogHelper::updateStartMultiPercentage(double value) { stick->setButtonsStartAccelerationMultiplier(value); } void MouseControlStickSettingsDialogHelper::updateMinAccelThreshold(double value) { stick->setButtonsMinAccelerationThreshold(value); } void MouseControlStickSettingsDialogHelper::updateMaxAccelThreshold(double value) { stick->setButtonsMaxAccelerationThreshold(value); } void MouseControlStickSettingsDialogHelper::updateAccelExtraDuration(double value) { stick->setButtonsAccelerationExtraDuration(value); } void MouseControlStickSettingsDialogHelper::updateReleaseSpringRadius(int value) { stick->setButtonsSpringDeadCircleMultiplier(value); } JoyControlStick *MouseControlStickSettingsDialogHelper::getStick() const { return stick; } AntiMicroX-antimicrox-b300273/src/mousedialog/uihelpers/mousecontrolsticksettingsdialoghelper.h000066400000000000000000000031711471077622000333540ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MOUSECONTROLSTICKSETTINGSDIALOGHELPER_H #define MOUSECONTROLSTICKSETTINGSDIALOGHELPER_H #include class JoyControlStick; class MouseControlStickSettingsDialogHelper : public QObject { Q_OBJECT public: explicit MouseControlStickSettingsDialogHelper(JoyControlStick *stick, QObject *parent = nullptr); JoyControlStick *getStick() const; public slots: void updateExtraAccelerationStatus(bool checked); void updateExtraAccelerationMultiplier(double value); void updateStartMultiPercentage(double value); void updateMinAccelThreshold(double value); void updateMaxAccelThreshold(double value); void updateAccelExtraDuration(double value); void updateReleaseSpringRadius(int value); private: JoyControlStick *stick; }; #endif // MOUSECONTROLSTICKSETTINGSDIALOGHELPER_H AntiMicroX-antimicrox-b300273/src/mousedialog/uihelpers/mousedpadsettingsdialoghelper.cpp000066400000000000000000000022271471077622000321020ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mousedpadsettingsdialoghelper.h" #include "joydpad.h" #include "joydpadbuttonwidget.h" #include MouseDpadSettingsDialogHelper::MouseDpadSettingsDialogHelper(JoyDPad *dpad, QObject *parent) : QObject(parent) { Q_ASSERT(dpad); this->dpad = dpad; } JoyDPad *MouseDpadSettingsDialogHelper::getDPad() const { return dpad; } AntiMicroX-antimicrox-b300273/src/mousedialog/uihelpers/mousedpadsettingsdialoghelper.h000066400000000000000000000022721471077622000315470ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MOUSEDPADSETTINGSDIALOGHELPER_H #define MOUSEDPADSETTINGSDIALOGHELPER_H #include class JoyDPad; class MouseDpadSettingsDialogHelper : public QObject { Q_OBJECT public: explicit MouseDpadSettingsDialogHelper(JoyDPad *dpad, QObject *parent = nullptr); JoyDPad *getDPad() const; private: JoyDPad *dpad; }; #endif // MOUSEDPADSETTINGSDIALOGHELPER_H AntiMicroX-antimicrox-b300273/src/mousehelper.cpp000066400000000000000000000024521471077622000220000ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mousehelper.h" #include MouseHelper::MouseHelper(QObject *parent) : QObject(parent) { springMouseMoving = false; previousCursorLocation[0] = 0; previousCursorLocation[1] = 0; pivotPoint[0] = -1; pivotPoint[1] = -1; mouseTimer.setParent(this); mouseTimer.setSingleShot(true); QObject::connect(&mouseTimer, &QTimer::timeout, this, &MouseHelper::resetSpringMouseMoving); } void MouseHelper::resetSpringMouseMoving() { springMouseMoving = false; } AntiMicroX-antimicrox-b300273/src/mousehelper.h000066400000000000000000000022671471077622000214510ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MOUSEHELPER_H #define MOUSEHELPER_H #include #include class MouseHelper : public QObject { Q_OBJECT public: explicit MouseHelper(QObject *parent = nullptr); bool springMouseMoving; int previousCursorLocation[2]; int pivotPoint[2]; QTimer mouseTimer; private slots: void resetSpringMouseMoving(); }; #endif // MOUSEHELPER_H AntiMicroX-antimicrox-b300273/src/pt1filter.cpp000066400000000000000000000026011471077622000213560ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "pt1filter.h" #include const double PT1Filter::FALLBACK_RATE = 200; PT1Filter::PT1Filter(double tau, double rate) { double period = qFuzzyIsNull(rate) ? 1 / FALLBACK_RATE : 1 / rate; // Since it is a fixed rate filter, precalculte delta_t/tau // to save one division during sample processing. m_dt_tau = period / tau; reset(); } /** * @brief Processes a new sample. * @returns New filter output value. */ double PT1Filter::process(double value) { m_value = m_value + m_dt_tau * (value - m_value); return m_value; }; /** * @brief Resets the filter state to default. */ void PT1Filter::reset() { m_value = 0; } AntiMicroX-antimicrox-b300273/src/pt1filter.h000066400000000000000000000025141471077622000210260ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once /** * @brief Implementation of a first order lag or PT1 filter. * Can be used for example to smooth noisy values a bit or detect envelopes. * @see https://en.wikipedia.org/wiki/Low-pass_filter */ class PT1Filter { public: PT1Filter(double tau = 1, double rate = 1); double process(double value); /** * @brief Get the current filter output value. * @returns Current filter output value. */ inline double getValue() const { return m_value; } void reset(); static const double FALLBACK_RATE; private: double m_dt_tau; double m_value; }; AntiMicroX-antimicrox-b300273/src/qtkeymapperbase.cpp000066400000000000000000000042721471077622000226470ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "qtkeymapperbase.h" #include const int QtKeyMapperBase::customQtKeyPrefix; const int QtKeyMapperBase::customKeyPrefix; const int QtKeyMapperBase::nativeKeyPrefix; QtKeyMapperBase::QtKeyMapperBase(QObject *parent) : QObject(parent) { } int QtKeyMapperBase::returnQtKey(int key, int scancode) { Q_UNUSED(scancode); return virtKeyToQtKeyHash.value(key); } int QtKeyMapperBase::returnVirtualKey(int qkey) { return qtKeyToVirtKeyHash.value(qkey); } bool QtKeyMapperBase::isModifier(int qkey) { bool modifier = false; int qtKeyValue = qkey & 0x0FFFFFFF; switch (qtKeyValue) { case Qt::Key_Shift: { modifier = true; break; } case Qt::Key_Control: { modifier = true; break; } case Qt::Key_Alt: { modifier = true; break; } case Qt::Key_Meta: { modifier = true; break; } } return modifier; } QtKeyMapperBase::charKeyInformation QtKeyMapperBase::getCharKeyInformation(QChar value) { charKeyInformation temp; temp.virtualkey = 0; temp.modifiers = Qt::NoModifier; if (virtkeyToCharKeyInfo.contains(value.unicode())) temp = virtkeyToCharKeyInfo.value(value.unicode()); return temp; } /** * @brief Obtain identifier string for key mapper. * @return Identifier string. */ QString QtKeyMapperBase::getIdentifier() { return identifier; } AntiMicroX-antimicrox-b300273/src/qtkeymapperbase.h000066400000000000000000000073461471077622000223210ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef QTKEYMAPPERBASE_H #define QTKEYMAPPERBASE_H #include #include class QtKeyMapperBase : public QObject { Q_OBJECT public: explicit QtKeyMapperBase(QObject *parent = nullptr); typedef struct _charKeyInformation { Qt::KeyboardModifiers modifiers; int virtualkey; } charKeyInformation; virtual int returnVirtualKey(int qkey); virtual int returnQtKey(int key, int scancode = 0); virtual bool isModifier(int qkey); charKeyInformation getCharKeyInformation(QChar value); QString getIdentifier(); static const int customQtKeyPrefix = 0x10000000; static const int customKeyPrefix = 0x20000000; static const int nativeKeyPrefix = 0x60000000; enum { AntKey_Shift_R = Qt::Key_Shift | customQtKeyPrefix, AntKey_Control_R = Qt::Key_Control | customQtKeyPrefix, AntKey_Shift_Lock = 0xffe6 | customKeyPrefix, // XK_Shift_Lock | 0x20000000 AntKey_Meta_R = Qt::Key_Meta | customQtKeyPrefix, AntKey_Alt_R = Qt::Key_Alt | customQtKeyPrefix, AntKey_KP_Divide = Qt::Key_Slash | customQtKeyPrefix, AntKey_KP_Multiply = Qt::Key_Asterisk | customQtKeyPrefix, AntKey_KP_Subtract = Qt::Key_Minus | customQtKeyPrefix, AntKey_KP_Add = Qt::Key_Plus | customQtKeyPrefix, AntKey_KP_Decimal = Qt::Key_Period | customQtKeyPrefix, AntKey_KP_Insert = Qt::Key_Insert | customQtKeyPrefix, AntKey_Delete = Qt::Key_Delete | customQtKeyPrefix, AntKey_KP_Delete = 0xff9f | customKeyPrefix, AntKey_KP_End = Qt::Key_End | customQtKeyPrefix, AntKey_KP_Down = Qt::Key_Down | customQtKeyPrefix, AntKey_KP_Prior = Qt::Key_PageUp | customQtKeyPrefix, AntKey_KP_Left = Qt::Key_Left | customQtKeyPrefix, AntKey_KP_Begin = Qt::Key_Clear | customQtKeyPrefix, AntKey_KP_Right = Qt::Key_Right | customQtKeyPrefix, AntKey_KP_Home = Qt::Key_Home | customQtKeyPrefix, AntKey_KP_Up = Qt::Key_Up | customQtKeyPrefix, AntKey_KP_Next = Qt::Key_PageDown | customQtKeyPrefix, AntKey_KP_Enter = 0xff8d | customKeyPrefix, AntKey_KP_0 = 0xffb0 | customKeyPrefix, AntKey_KP_1 = 0xffb1 | customKeyPrefix, AntKey_KP_2 = 0xffb2 | customKeyPrefix, AntKey_KP_3 = 0xffb3 | customKeyPrefix, AntKey_KP_4 = 0xffb4 | customKeyPrefix, AntKey_KP_5 = 0xffb5 | customKeyPrefix, AntKey_KP_6 = 0xffb6 | customKeyPrefix, AntKey_KP_7 = 0xffb7 | customKeyPrefix, AntKey_KP_8 = 0xffb8 | customKeyPrefix, AntKey_KP_9 = 0xffb9 | customKeyPrefix }; protected: virtual void populateMappingHashes() = 0; virtual void populateCharKeyInformation() = 0; QHash qtKeyToVirtKeyHash; QHash virtKeyToQtKeyHash; QHash virtkeyToCharKeyInfo; // Unicode representation -> VK+Modifier information QString identifier; }; #endif // QTKEYMAPPERBASE_H AntiMicroX-antimicrox-b300273/src/qtuinputkeymapper.cpp000066400000000000000000000437651471077622000232730ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include //#include #include #include #include #include "qtuinputkeymapper.h" QtUInputKeyMapper::QtUInputKeyMapper(QObject *parent) : QtKeyMapperBase(parent) { identifier = "uinput"; populateMappingHashes(); populateCharKeyInformation(); } void QtUInputKeyMapper::populateAlphaHashes() { // Map lowercase alpha keys qtKeyToVirtKeyHash[Qt::Key_A] = KEY_A; qtKeyToVirtKeyHash[Qt::Key_B] = KEY_B; qtKeyToVirtKeyHash[Qt::Key_C] = KEY_C; qtKeyToVirtKeyHash[Qt::Key_D] = KEY_D; qtKeyToVirtKeyHash[Qt::Key_E] = KEY_E; qtKeyToVirtKeyHash[Qt::Key_F] = KEY_F; qtKeyToVirtKeyHash[Qt::Key_G] = KEY_G; qtKeyToVirtKeyHash[Qt::Key_H] = KEY_H; qtKeyToVirtKeyHash[Qt::Key_I] = KEY_I; qtKeyToVirtKeyHash[Qt::Key_J] = KEY_J; qtKeyToVirtKeyHash[Qt::Key_K] = KEY_K; qtKeyToVirtKeyHash[Qt::Key_L] = KEY_L; qtKeyToVirtKeyHash[Qt::Key_M] = KEY_M; qtKeyToVirtKeyHash[Qt::Key_N] = KEY_N; qtKeyToVirtKeyHash[Qt::Key_O] = KEY_O; qtKeyToVirtKeyHash[Qt::Key_P] = KEY_P; qtKeyToVirtKeyHash[Qt::Key_Q] = KEY_Q; qtKeyToVirtKeyHash[Qt::Key_R] = KEY_R; qtKeyToVirtKeyHash[Qt::Key_S] = KEY_S; qtKeyToVirtKeyHash[Qt::Key_T] = KEY_T; qtKeyToVirtKeyHash[Qt::Key_U] = KEY_U; qtKeyToVirtKeyHash[Qt::Key_V] = KEY_V; qtKeyToVirtKeyHash[Qt::Key_W] = KEY_W; qtKeyToVirtKeyHash[Qt::Key_X] = KEY_X; qtKeyToVirtKeyHash[Qt::Key_Y] = KEY_Y; qtKeyToVirtKeyHash[Qt::Key_Z] = KEY_Z; } void QtUInputKeyMapper::populateFKeyHashes() { // Map F1 - F10 for (int i = 0; i <= (KEY_F10 - KEY_F1); i++) qtKeyToVirtKeyHash[Qt::Key_F1 + i] = KEY_F1 + i; // Map F11 and F12 for (int i = 0; i <= (KEY_F12 - KEY_F11); i++) qtKeyToVirtKeyHash[Qt::Key_F11 + i] = KEY_F11 + i; // Map F13 - F24 for (int i = 0; i <= (KEY_F24 - KEY_F13); i++) qtKeyToVirtKeyHash[Qt::Key_F13 + i] = KEY_F13 + i; } void QtUInputKeyMapper::populateNumPadHashes() { // Map Numpad 0 qtKeyToVirtKeyHash[AntKey_KP_0] = KEY_KP0; // Map Numpad 1 - 3 for (int i = 0; i <= (KEY_KP3 - KEY_KP1); i++) qtKeyToVirtKeyHash[AntKey_KP_1 + i] = KEY_KP1 + i; // Map Numpad 4 - 6 for (int i = 0; i <= (KEY_KP6 - KEY_KP4); i++) qtKeyToVirtKeyHash[AntKey_KP_4 + i] = KEY_KP4 + i; // Map Numpad 7 - 9 for (int i = 0; i <= (KEY_KP9 - KEY_KP7); i++) qtKeyToVirtKeyHash[AntKey_KP_7 + i] = KEY_KP7 + i; } void QtUInputKeyMapper::populateSpecialCharHashes() { qtKeyToVirtKeyHash[Qt::Key_QuoteLeft] = KEY_GRAVE; qtKeyToVirtKeyHash[Qt::Key_Minus] = KEY_MINUS; qtKeyToVirtKeyHash[Qt::Key_Equal] = KEY_EQUAL; qtKeyToVirtKeyHash[Qt::Key_BracketLeft] = KEY_LEFTBRACE; qtKeyToVirtKeyHash[Qt::Key_BracketRight] = KEY_RIGHTBRACE; qtKeyToVirtKeyHash[Qt::Key_Semicolon] = KEY_SEMICOLON; qtKeyToVirtKeyHash[Qt::Key_Apostrophe] = KEY_APOSTROPHE; qtKeyToVirtKeyHash[Qt::Key_Comma] = KEY_COMMA; qtKeyToVirtKeyHash[Qt::Key_Period] = KEY_DOT; qtKeyToVirtKeyHash[Qt::Key_Slash] = KEY_SLASH; qtKeyToVirtKeyHash[Qt::Key_Backslash] = KEY_BACKSLASH; } void QtUInputKeyMapper::populateMappingHashes() { if (qtKeyToVirtKeyHash.isEmpty()) { mapMiscKeysQtUinput(qtKeyToVirtKeyHash); mapCursorMovesKeysQtUinput(qtKeyToVirtKeyHash); mapModifiersKeysQtUinput(qtKeyToVirtKeyHash); mapMediaKeysQtUinput(qtKeyToVirtKeyHash); // Map 0-9 keys for (int i = 0; i <= (KEY_9 - KEY_1); i++) qtKeyToVirtKeyHash[Qt::Key_1 + i] = KEY_1 + i; qtKeyToVirtKeyHash[Qt::Key_0] = KEY_0; populateSpecialCharHashes(); populateAlphaHashes(); populateFKeyHashes(); populateNumPadHashes(); // Map custom defined keys qtKeyToVirtKeyHash[AntKey_Shift_R] = KEY_RIGHTSHIFT; qtKeyToVirtKeyHash[AntKey_Control_R] = KEY_RIGHTCTRL; qtKeyToVirtKeyHash[AntKey_Alt_R] = KEY_RIGHTALT; qtKeyToVirtKeyHash[AntKey_KP_Multiply] = KEY_KPASTERISK; mapKeypadKeysQtUinput(qtKeyToVirtKeyHash); // International input method support keys // Misc Functions qtKeyToVirtKeyHash[Qt::Key_Mode_switch] = KEY_SWITCHVIDEOMODE; mapJapanKeysQtUinput(qtKeyToVirtKeyHash); #ifdef XK_KOREAN mapKoreanKeysQtUinput(qtKeyToVirtKeyHash); #endif // XK_KOREAN // Populate other hash. Flip key and value so mapping // goes VK -> Qt Key. QHashIterator iter(qtKeyToVirtKeyHash); while (iter.hasNext()) { iter.next(); virtKeyToQtKeyHash[iter.value()] = iter.key(); } // Override some entries. virtKeyToQtKeyHash[KEY_KP0] = AntKey_KP_0; virtKeyToQtKeyHash[KEY_KP1] = AntKey_KP_1; virtKeyToQtKeyHash[KEY_KP2] = AntKey_KP_2; virtKeyToQtKeyHash[KEY_KP3] = AntKey_KP_3; virtKeyToQtKeyHash[KEY_KP4] = AntKey_KP_4; virtKeyToQtKeyHash[KEY_KP5] = AntKey_KP_5; virtKeyToQtKeyHash[KEY_KP6] = AntKey_KP_6; virtKeyToQtKeyHash[KEY_KP7] = AntKey_KP_7; virtKeyToQtKeyHash[KEY_KP8] = AntKey_KP_8; virtKeyToQtKeyHash[KEY_KP9] = AntKey_KP_9; virtKeyToQtKeyHash[KEY_CALC] = Qt::Key_Launch1; } } void QtUInputKeyMapper::populateCharKeyInformation() { virtkeyToCharKeyInfo.clear(); char16_t unicodeTempValue = 0; int listIndex = 0; charKeyInformation charKeyInfo; charKeyInfo.modifiers = Qt::NoModifier; charKeyInfo.virtualkey = 0; // Map 0-9 keys for (char16_t i = QChar('1').unicode(); i <= QChar('9').unicode(); i++) addVirtualKeyToHash(KEY_1 + i, i, charKeyInfo); addVirtualKeyToHash(KEY_0, QChar('0'), charKeyInfo); addVirtualKeyToHash(KEY_MINUS, QChar('-'), charKeyInfo); addVirtualKeyToHash(KEY_EQUAL, QChar('='), charKeyInfo); QList tempKeys; tempKeys.append(KEY_A); tempKeys.append(KEY_B); tempKeys.append(KEY_C); tempKeys.append(KEY_D); tempKeys.append(KEY_E); tempKeys.append(KEY_F); tempKeys.append(KEY_G); tempKeys.append(KEY_H); tempKeys.append(KEY_I); tempKeys.append(KEY_J); tempKeys.append(KEY_K); tempKeys.append(KEY_L); tempKeys.append(KEY_M); tempKeys.append(KEY_N); tempKeys.append(KEY_O); tempKeys.append(KEY_P); tempKeys.append(KEY_Q); tempKeys.append(KEY_R); tempKeys.append(KEY_S); tempKeys.append(KEY_T); tempKeys.append(KEY_U); tempKeys.append(KEY_V); tempKeys.append(KEY_W); tempKeys.append(KEY_X); tempKeys.append(KEY_Y); tempKeys.append(KEY_Z); unicodeTempValue = QChar('a').unicode(); QListIterator tempIter(tempKeys); while (tempIter.hasNext()) { addVirtualKeyToHash(tempIter.next(), unicodeTempValue, charKeyInfo); unicodeTempValue++; } tempIter.toFront(); charKeyInfo.modifiers = Qt::ShiftModifier; unicodeTempValue = QChar('A').unicode(); while (tempIter.hasNext()) { addVirtualKeyToHash(tempIter.next(), unicodeTempValue, charKeyInfo); unicodeTempValue++; } tempKeys.clear(); charKeyInfo.modifiers = Qt::ShiftModifier; tempKeys.append(QChar('!').unicode()); tempKeys.append(QChar('@').unicode()); tempKeys.append(QChar('#').unicode()); tempKeys.append(QChar('$').unicode()); tempKeys.append(QChar('%').unicode()); tempKeys.append(QChar('^').unicode()); tempKeys.append(QChar('&').unicode()); tempKeys.append(QChar('*').unicode()); tempKeys.append(QChar('(').unicode()); tempKeys.append(QChar(')').unicode()); tempKeys.append(QChar('_').unicode()); tempKeys.append(QChar('+').unicode()); tempIter = QListIterator(tempKeys); listIndex = 0; while (tempIter.hasNext()) { addVirtualKeyToHash(KEY_1 + listIndex, QChar(tempIter.next()), charKeyInfo); listIndex++; } tempKeys.clear(); charKeyInfo.modifiers = Qt::NoModifier; addVirtualKeyToHash(KEY_SPACE, QChar(' '), charKeyInfo); addVirtualKeyToHash(KEY_LEFTBRACE, QChar('['), charKeyInfo); addVirtualKeyToHash(KEY_RIGHTBRACE, QChar(']'), charKeyInfo); addVirtualKeyToHash(KEY_BACKSLASH, QChar('\\'), charKeyInfo); addVirtualKeyToHash(KEY_SEMICOLON, QChar(';'), charKeyInfo); addVirtualKeyToHash(KEY_APOSTROPHE, QChar('\''), charKeyInfo); addVirtualKeyToHash(KEY_COMMA, QChar(','), charKeyInfo); addVirtualKeyToHash(KEY_DOT, QChar('.'), charKeyInfo); addVirtualKeyToHash(KEY_SLASH, QChar('/'), charKeyInfo); addVirtualKeyToHash(KEY_LEFTBRACE, QChar('{'), charKeyInfo); addVirtualKeyToHash(KEY_RIGHTBRACE, QChar('}'), charKeyInfo); addVirtualKeyToHash(KEY_BACKSLASH, QChar('|'), charKeyInfo); addVirtualKeyToHash(KEY_SEMICOLON, QChar(':'), charKeyInfo); addVirtualKeyToHash(KEY_APOSTROPHE, QChar('"'), charKeyInfo); addVirtualKeyToHash(KEY_COMMA, QChar('<'), charKeyInfo); addVirtualKeyToHash(KEY_DOT, QChar('>'), charKeyInfo); addVirtualKeyToHash(KEY_SLASH, QChar('?'), charKeyInfo); } void QtUInputKeyMapper::addVirtualKeyToHash(int key, QChar character, charKeyInformation &charKeyInfo) { charKeyInfo.virtualkey = key; virtkeyToCharKeyInfo.insert(character.unicode(), charKeyInfo); } void QtUInputKeyMapper::mapMiscKeysQtUinput(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_Escape] = KEY_ESC; qtKeyToVirtKeyHash[Qt::Key_Tab] = KEY_TAB; qtKeyToVirtKeyHash[Qt::Key_Backspace] = KEY_BACKSPACE; qtKeyToVirtKeyHash[Qt::Key_Return] = KEY_ENTER; qtKeyToVirtKeyHash[Qt::Key_Insert] = KEY_INSERT; qtKeyToVirtKeyHash[Qt::Key_Delete] = KEY_DELETE; qtKeyToVirtKeyHash[Qt::Key_Pause] = KEY_PAUSE; qtKeyToVirtKeyHash[Qt::Key_Print] = KEY_PRINT; qtKeyToVirtKeyHash[Qt::Key_Space] = KEY_SPACE; qtKeyToVirtKeyHash[Qt::Key_SysReq] = KEY_SYSRQ; qtKeyToVirtKeyHash[Qt::Key_PowerOff] = KEY_POWER; qtKeyToVirtKeyHash[Qt::Key_Stop] = KEY_STOP; qtKeyToVirtKeyHash[Qt::Key_Refresh] = KEY_REFRESH; qtKeyToVirtKeyHash[Qt::Key_Copy] = KEY_COPY; qtKeyToVirtKeyHash[Qt::Key_Paste] = KEY_PASTE; // qtKeyToVirtKeyHash[Qt::Key_Search] = KEY_FIND; qtKeyToVirtKeyHash[Qt::Key_Cut] = KEY_CUT; qtKeyToVirtKeyHash[Qt::Key_Sleep] = KEY_SLEEP; qtKeyToVirtKeyHash[Qt::Key_Calculator] = KEY_CALC; qtKeyToVirtKeyHash[Qt::Key_Launch0] = KEY_COMPUTER; qtKeyToVirtKeyHash[Qt::Key_Launch1] = KEY_CALC; qtKeyToVirtKeyHash[Qt::Key_Launch2] = KEY_PROG1; qtKeyToVirtKeyHash[Qt::Key_Launch3] = KEY_PROG2; qtKeyToVirtKeyHash[Qt::Key_Launch4] = KEY_PROG3; qtKeyToVirtKeyHash[Qt::Key_Launch5] = KEY_PROG4; qtKeyToVirtKeyHash[Qt::Key_HomePage] = KEY_HOMEPAGE; qtKeyToVirtKeyHash[Qt::Key_LaunchMail] = KEY_MAIL; qtKeyToVirtKeyHash[Qt::Key_Back] = KEY_BACK; qtKeyToVirtKeyHash[Qt::Key_Favorites] = KEY_FAVORITES; qtKeyToVirtKeyHash[Qt::Key_Forward] = KEY_FORWARD; qtKeyToVirtKeyHash[Qt::Key_Suspend] = KEY_SUSPEND; qtKeyToVirtKeyHash[Qt::Key_Close] = KEY_CLOSE; // qtKeyToVirtKeyHash[Qt::Key_Search] = KEY_SEARCH; qtKeyToVirtKeyHash[Qt::Key_Camera] = KEY_CAMERA; qtKeyToVirtKeyHash[Qt::Key_MonBrightnessUp] = KEY_BRIGHTNESSUP; qtKeyToVirtKeyHash[Qt::Key_MonBrightnessDown] = KEY_BRIGHTNESSDOWN; qtKeyToVirtKeyHash[Qt::Key_Send] = KEY_SEND; qtKeyToVirtKeyHash[Qt::Key_Reply] = KEY_REPLY; qtKeyToVirtKeyHash[Qt::Key_Forward] = KEY_FORWARDMAIL; qtKeyToVirtKeyHash[Qt::Key_Save] = KEY_SAVE; qtKeyToVirtKeyHash[Qt::Key_Documents] = KEY_DOCUMENTS; qtKeyToVirtKeyHash[Qt::Key_Battery] = KEY_BATTERY; qtKeyToVirtKeyHash[Qt::Key_Bluetooth] = KEY_BLUETOOTH; qtKeyToVirtKeyHash[Qt::Key_WLAN] = KEY_WLAN; qtKeyToVirtKeyHash[Qt::Key_Cancel] = KEY_CANCEL; qtKeyToVirtKeyHash[Qt::Key_Shop] = KEY_SHOP; qtKeyToVirtKeyHash[Qt::Key_Finance] = KEY_FINANCE; qtKeyToVirtKeyHash[Qt::Key_Question] = KEY_QUESTION; qtKeyToVirtKeyHash[Qt::Key_BassBoost] = KEY_BASSBOOST; } void QtUInputKeyMapper::mapCursorMovesKeysQtUinput(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_Home] = KEY_HOME; qtKeyToVirtKeyHash[Qt::Key_End] = KEY_END; qtKeyToVirtKeyHash[Qt::Key_Left] = KEY_LEFT; qtKeyToVirtKeyHash[Qt::Key_Up] = KEY_UP; qtKeyToVirtKeyHash[Qt::Key_Right] = KEY_RIGHT; qtKeyToVirtKeyHash[Qt::Key_Down] = KEY_DOWN; qtKeyToVirtKeyHash[Qt::Key_PageUp] = KEY_PAGEUP; qtKeyToVirtKeyHash[Qt::Key_PageDown] = KEY_PAGEDOWN; } void QtUInputKeyMapper::mapModifiersKeysQtUinput(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_Shift] = KEY_LEFTSHIFT; qtKeyToVirtKeyHash[Qt::Key_Control] = KEY_LEFTCTRL; qtKeyToVirtKeyHash[Qt::Key_Alt] = KEY_LEFTALT; qtKeyToVirtKeyHash[Qt::Key_CapsLock] = KEY_CAPSLOCK; qtKeyToVirtKeyHash[Qt::Key_NumLock] = KEY_NUMLOCK; qtKeyToVirtKeyHash[Qt::Key_ScrollLock] = KEY_SCROLLLOCK; qtKeyToVirtKeyHash[Qt::Key_Meta] = KEY_LEFTMETA; qtKeyToVirtKeyHash[AntKey_Meta_R] = KEY_RIGHTMETA; qtKeyToVirtKeyHash[Qt::Key_Menu] = KEY_COMPOSE; qtKeyToVirtKeyHash[Qt::Key_Help] = KEY_HELP; } void QtUInputKeyMapper::mapKeypadKeysQtUinput(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[AntKey_KP_Enter] = KEY_KPENTER; qtKeyToVirtKeyHash[AntKey_KP_Home] = KEY_HOME; qtKeyToVirtKeyHash[AntKey_KP_Left] = KEY_LEFT; qtKeyToVirtKeyHash[AntKey_KP_Up] = KEY_UP; qtKeyToVirtKeyHash[AntKey_KP_Right] = KEY_RIGHT; qtKeyToVirtKeyHash[AntKey_KP_Down] = KEY_DOWN; qtKeyToVirtKeyHash[AntKey_KP_Prior] = KEY_PAGEUP; qtKeyToVirtKeyHash[AntKey_KP_Next] = KEY_PAGEDOWN; qtKeyToVirtKeyHash[AntKey_KP_End] = KEY_END; qtKeyToVirtKeyHash[AntKey_KP_Begin] = KEY_LEFTMETA; qtKeyToVirtKeyHash[AntKey_KP_Insert] = KEY_INSERT; qtKeyToVirtKeyHash[AntKey_KP_Add] = KEY_KPPLUS; qtKeyToVirtKeyHash[AntKey_KP_Subtract] = KEY_KPMINUS; qtKeyToVirtKeyHash[AntKey_KP_Delete] = KEY_KPDOT; qtKeyToVirtKeyHash[AntKey_KP_Decimal] = KEY_KPDOT; qtKeyToVirtKeyHash[AntKey_KP_Divide] = KEY_KPSLASH; qtKeyToVirtKeyHash[AntKey_KP_1] = KEY_KP1; qtKeyToVirtKeyHash[AntKey_KP_2] = KEY_KP2; qtKeyToVirtKeyHash[AntKey_KP_3] = KEY_KP3; qtKeyToVirtKeyHash[AntKey_KP_4] = KEY_KP4; qtKeyToVirtKeyHash[AntKey_KP_5] = KEY_KP5; qtKeyToVirtKeyHash[AntKey_KP_6] = KEY_KP6; qtKeyToVirtKeyHash[AntKey_KP_7] = KEY_KP7; qtKeyToVirtKeyHash[AntKey_KP_8] = KEY_KP8; qtKeyToVirtKeyHash[AntKey_KP_9] = KEY_KP9; qtKeyToVirtKeyHash[AntKey_KP_0] = KEY_KP0; } void QtUInputKeyMapper::mapJapanKeysQtUinput(QHash &qtKeyToVirtKeyHash) { // qtKeyToVirtKeyHash[Qt::Key_Kanji] = XK_Kanji; qtKeyToVirtKeyHash[Qt::Key_Muhenkan] = KEY_MUHENKAN; qtKeyToVirtKeyHash[Qt::Key_Henkan] = KEY_HENKAN; qtKeyToVirtKeyHash[Qt::Key_Romaji] = KEY_RO; qtKeyToVirtKeyHash[Qt::Key_Hiragana] = KEY_HIRAGANA; qtKeyToVirtKeyHash[Qt::Key_Katakana] = KEY_KATAKANA; qtKeyToVirtKeyHash[Qt::Key_Hiragana_Katakana] = KEY_KATAKANAHIRAGANA; // qtKeyToVirtKeyHash[Qt::Key_Zenkaku] = XK_Zenkaku; // qtKeyToVirtKeyHash[Qt::Key_Hankaku] = XK_Hankaku; qtKeyToVirtKeyHash[Qt::Key_Zenkaku_Hankaku] = KEY_ZENKAKUHANKAKU; /* qtKeyToVirtKeyHash[Qt::Key_Touroku] = XK_Touroku; qtKeyToVirtKeyHash[Qt::Key_Massyo] = XK_Massyo; qtKeyToVirtKeyHash[Qt::Key_Kana_Lock] = XK_Kana_Lock; qtKeyToVirtKeyHash[Qt::Key_Kana_Shift] = XK_Kana_Shift; qtKeyToVirtKeyHash[Qt::Key_Eisu_Shift] = XK_Eisu_Shift; qtKeyToVirtKeyHash[Qt::Key_Eisu_toggle] = XK_Eisu_toggle; qtKeyToVirtKeyHash[Qt::Key_Codeinput] = XK_Kanji_Bangou; qtKeyToX11KeySym[Qt::Key_MultipleCandidate] = XK_Zen_Koho; qtKeyToX11KeySym[Qt::Key_PreviousCandidate] = XK_Mae_Koho;*/ } void QtUInputKeyMapper::mapKoreanKeysQtUinput(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_Hangul] = KEY_HANGEUL; /* qtKeyToVirtKeyHash[Qt::Key_Hangul_Start] = XK_Hangul_Start; qtKeyToVirtKeyHash[Qt::Key_Hangul_End] = XK_Hangul_End; qtKeyToVirtKeyHash[Qt::Key_Hangul_Hanja] = KEY_HANJA; qtKeyToVirtKeyHash[Qt::Key_Hangul_Jamo] = XK_Hangul_Jamo; qtKeyToVirtKeyHash[Qt::Key_Hangul_Romaja] = XK_Hangul_Romaja; //qtKeyToX11KeySym[Qt::Key_Codeinput] = XK_Hangul_Codeinput; qtKeyToVirtKeyHash[Qt::Key_Hangul_Jeonja] = XK_Hangul_Jeonja; qtKeyToVirtKeyHash[Qt::Key_Hangul_Banja] = XK_Hangul_Banja; qtKeyToVirtKeyHash[Qt::Key_Hangul_PreHanja] = XK_Hangul_PreHanja; qtKeyToVirtKeyHash[Qt::Key_Hangul_PostHanja] = XK_Hangul_PostHanja; //qtKeyToX11KeySym[Qt::Key_SingleCandidate] = XK_Hangul_SingleCandidate; //qtKeyToX11KeySym[Qt::Key_MultipleCandidate] = XK_Hangul_MultipleCandidate; //qtKeyToX11KeySym[Qt::Key_PreviousCandidate] = XK_Hangul_PreviousCandidate; qtKeyToVirtKeyHash[Qt::Key_Hangul_Special] = XK_Hangul_Special; //qtKeyToX11KeySym[Qt::Key_Mode_switch] = XK_Hangul_switch;*/ } void QtUInputKeyMapper::mapMediaKeysQtUinput(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_VolumeDown] = KEY_VOLUMEDOWN; qtKeyToVirtKeyHash[Qt::Key_VolumeMute] = KEY_MUTE; qtKeyToVirtKeyHash[Qt::Key_VolumeUp] = KEY_VOLUMEUP; qtKeyToVirtKeyHash[Qt::Key_MediaPlay] = KEY_PLAYPAUSE; qtKeyToVirtKeyHash[Qt::Key_MediaStop] = KEY_STOPCD; qtKeyToVirtKeyHash[Qt::Key_MediaPrevious] = KEY_PREVIOUSSONG; qtKeyToVirtKeyHash[Qt::Key_MediaNext] = KEY_NEXTSONG; qtKeyToVirtKeyHash[Qt::Key_MediaRecord] = KEY_RECORD; qtKeyToVirtKeyHash[Qt::Key_LaunchMedia] = KEY_MEDIA; } AntiMicroX-antimicrox-b300273/src/qtuinputkeymapper.h000066400000000000000000000035571471077622000227330ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef QTUINPUTKEYMAPPER_H #define QTUINPUTKEYMAPPER_H #include "qtkeymapperbase.h" class QtUInputKeyMapper : public QtKeyMapperBase { Q_OBJECT public: explicit QtUInputKeyMapper(QObject *parent = nullptr); protected: void populateMappingHashes() override; void populateCharKeyInformation() override; void populateAlphaHashes(); void populateFKeyHashes(); void populateNumPadHashes(); void populateSpecialCharHashes(); private: void addVirtualKeyToHash(int key, QChar character, charKeyInformation &charKeyInfo); void mapMiscKeysQtUinput(QHash &qtKeyToVirtKeyHash); void mapCursorMovesKeysQtUinput(QHash &qtKeyToVirtKeyHash); void mapModifiersKeysQtUinput(QHash &qtKeyToVirtKeyHash); void mapKeypadKeysQtUinput(QHash &qtKeyToVirtKeyHash); void mapJapanKeysQtUinput(QHash &qtKeyToVirtKeyHash); void mapKoreanKeysQtUinput(QHash &qtKeyToVirtKeyHash); void mapMediaKeysQtUinput(QHash &qtKeyToVirtKeyHash); }; #endif // QTUINPUTKEYMAPPER_H AntiMicroX-antimicrox-b300273/src/qtvmultikeymapper.cpp000066400000000000000000000162151471077622000232550ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "qtvmultikeymapper.h" QtVMultiKeyMapper::QtVMultiKeyMapper(QObject *parent) : QtKeyMapperBase(parent) { identifier = "vmulti"; populateMappingHashes(); } void QtVMultiKeyMapper::populateMappingHashes() { if (qtKeyToVirtualKey.isEmpty()) { // Map A - Z keys for (int i = 0; i <= (Qt::Key_Z - Qt::Key_A); i++) { qtKeyToVirtualKey[Qt::Key_A + i] = 0x04 + i; } // Map 1 - 9 numeric keys for (int i = 0; i <= (Qt::Key_9 - Qt::Key_1); i++) { qtKeyToVirtualKey[Qt::Key_1 + i] = 0x1E + i; } // Map 0 numeric key qtKeyToVirtualKey[Qt::Key_0] = 0x27; qtKeyToVirtualKey[Qt::Key_Return] = 0x28; qtKeyToVirtualKey[Qt::Key_Escape] = 0x29; qtKeyToVirtualKey[Qt::Key_Backspace] = 0x2A; qtKeyToVirtualKey[Qt::Key_Tab] = 0x2B; qtKeyToVirtualKey[Qt::Key_Space] = 0x2C; qtKeyToVirtualKey[Qt::Key_Minus] = 0x2D; qtKeyToVirtualKey[Qt::Key_Equal] = 0x2E; qtKeyToVirtualKey[Qt::Key_BracketLeft] = 0x2F; qtKeyToVirtualKey[Qt::Key_BracketRight] = 0x30; qtKeyToVirtualKey[Qt::Key_Backslash] = 0x31; qtKeyToVirtualKey[Qt::Key_NumberSign] = 0x32; qtKeyToVirtualKey[Qt::Key_Semicolon] = 0x33; qtKeyToVirtualKey[Qt::Key_Apostrophe] = 0x34; qtKeyToVirtualKey[Qt::Key_QuoteLeft] = 0x35; qtKeyToVirtualKey[Qt::Key_Comma] = 0x36; qtKeyToVirtualKey[Qt::Key_Period] = 0x37; qtKeyToVirtualKey[Qt::Key_Slash] = 0x38; qtKeyToVirtualKey[Qt::Key_CapsLock] = 0x39; // Map F1 - F12 keys for (int i = 0; i <= (Qt::Key_F12 - Qt::Key_F1); i++) { qtKeyToVirtualKey[Qt::Key_F1 + i] = 0x3A + i; } qtKeyToVirtualKey[Qt::Key_Print] = 0x46; qtKeyToVirtualKey[Qt::Key_ScrollLock] = 0x47; qtKeyToVirtualKey[Qt::Key_Pause] = 0x48; qtKeyToVirtualKey[Qt::Key_Insert] = 0x49; qtKeyToVirtualKey[Qt::Key_Home] = 0x4A; qtKeyToVirtualKey[Qt::Key_PageUp] = 0x4B; qtKeyToVirtualKey[Qt::Key_Delete] = 0x4C; qtKeyToVirtualKey[Qt::Key_End] = 0x4D; qtKeyToVirtualKey[Qt::Key_PageDown] = 0x4E; qtKeyToVirtualKey[Qt::Key_Right] = 0x4F; qtKeyToVirtualKey[Qt::Key_Left] = 0x50; qtKeyToVirtualKey[Qt::Key_Down] = 0x51; qtKeyToVirtualKey[Qt::Key_Up] = 0x52; qtKeyToVirtualKey[Qt::Key_NumLock] = 0x53; qtKeyToVirtualKey[AntKey_KP_Divide] = 0x54; qtKeyToVirtualKey[AntKey_KP_Multiply] = 0x55; qtKeyToVirtualKey[AntKey_KP_Subtract] = 0x56; qtKeyToVirtualKey[AntKey_KP_Add] = 0x57; qtKeyToVirtualKey[Qt::Key_Enter] = 0x58; // Map Numpad 1 - 9 keys for (int i = 0; i <= (AntKey_KP_9 - AntKey_KP_1); i++) { qtKeyToVirtualKey[AntKey_KP_1 + i] = 0x59 + i; } // Map Numpad 0 key qtKeyToVirtualKey[AntKey_KP_0] = 0x62; qtKeyToVirtualKey[AntKey_KP_Decimal] = 0x63; // qtKeyToVirtualKey[Qt::Key_Backslash] = 0x64; qtKeyToVirtualKey[Qt::Key_ApplicationLeft] = 0x65; qtKeyToVirtualKey[Qt::Key_PowerOff] = 0x66; // qtKeyToVirtualKey[] = 0x67; for (int i = 0; i <= (Qt::Key_F24 - Qt::Key_F13); i++) { qtKeyToVirtualKey[Qt::Key_F13 + i] = 0x68 + i; } qtKeyToVirtualKey[Qt::Key_Execute] = 0x74; qtKeyToVirtualKey[Qt::Key_Help] = 0x75; qtKeyToVirtualKey[Qt::Key_Menu] = 0x76; qtKeyToVirtualKey[Qt::Key_Select] = 0x77; qtKeyToVirtualKey[Qt::Key_Stop] = 0x78; // qtKeyToVirtualKey[] = 0x79; qtKeyToVirtualKey[Qt::Key_Undo] = 0x7A; qtKeyToVirtualKey[Qt::Key_Cut] = 0x7B; qtKeyToVirtualKey[Qt::Key_Copy] = 0x7C; qtKeyToVirtualKey[Qt::Key_Paste] = 0x7D; qtKeyToVirtualKey[Qt::Key_Find] = 0x7E; qtKeyToVirtualKey[Qt::Key_VolumeMute] = 0x7F; qtKeyToVirtualKey[Qt::Key_VolumeUp] = 0x80; qtKeyToVirtualKey[Qt::Key_VolumeDown] = 0x81; // qtKeyToVirtualKey[] = 0x82; // qtKeyToVirtualKey[] = 0x83; // qtKeyToVirtualKey[] = 0x84; // qtKeyToVirtualKey[] = 0x85; // International Keys? // qtKeyToVirtualKey[] = 0x87; // qtKeyToVirtualKey[] = 0x88; // qtKeyToVirtualKey[] = 0x89; // qtKeyToVirtualKey[] = 0x8A; // qtKeyToVirtualKey[] = 0x8B; // qtKeyToVirtualKey[] = 0x8C; // qtKeyToVirtualKey[] = 0x8D; // qtKeyToVirtualKey[] = 0x8E; // qtKeyToVirtualKey[] = 0x8F; qtKeyToVirtualKey[Qt::Key_Control] = 0xE0; qtKeyToVirtualKey[Qt::Key_Shift] = 0xE1; qtKeyToVirtualKey[Qt::Key_Alt] = 0xE2; qtKeyToVirtualKey[Qt::Key_Meta] = 0xE3; qtKeyToVirtualKey[AntKey_Control_R] = 0xE4; qtKeyToVirtualKey[AntKey_Shift_R] = 0xE5; qtKeyToVirtualKey[AntKey_Meta_R] = 0xE7; qtKeyToVirtualKey[Qt::Key_MediaPause] = 0xB1 | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_MediaNext] = 0xB5 | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_MediaPrevious] = 0xB6 | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_MediaStop] = 0xB7 | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_HomePage] = 0x189 | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_Launch0] = 0x194 | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_Calculator] = 0x192 | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_Favorites] = 0x22a | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_Search] = 0x221 | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_Stop] = 0x226 | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_Back] = 0x224 | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_LaunchMedia] = 0x87 | consumerUsagePagePrefix; qtKeyToVirtualKey[Qt::Key_LaunchMail] = 0x18a | consumerUsagePagePrefix; // Populate other hash. Flip key and value so mapping // goes VK -> Qt Key. QHashIterator iter(qtKeyToVirtualKey); while (iter.hasNext()) { iter.next(); virtualKeyToQtKey[iter.value()] = iter.key(); } } } void QtVMultiKeyMapper::populateCharKeyInformation() {} AntiMicroX-antimicrox-b300273/src/qtvmultikeymapper.h000066400000000000000000000023551471077622000227220ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef QTVMULTIKEYMAPPER_H #define QTVMULTIKEYMAPPER_H #include "qtkeymapperbase.h" class QtVMultiKeyMapper : public QtKeyMapperBase { public: explicit QtVMultiKeyMapper(QObject *parent = nullptr); static const int consumerUsagePagePrefix = 0x12000; protected: void populateMappingHashes() override; void populateCharKeyInformation() override; }; #endif // QTVMULTIKEYMAPPER_H AntiMicroX-antimicrox-b300273/src/qtwinkeymapper.cpp000066400000000000000000000377271471077622000225450ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include //#include #include #include "qtwinkeymapper.h" #include "winextras.h" #include static QHash initDynamicKeyMapping() { QHash temp; temp[VK_OEM_1] = 0; // temp[VK_OEM_PLUS] = 0; // temp[VK_OEM_COMMA] = 0; // temp[VK_OEM_MINUS] = 0; // temp[VK_OEM_PERIOD] = 0; temp[VK_OEM_2] = 0; temp[VK_OEM_3] = 0; temp[VK_OEM_4] = 0; temp[VK_OEM_5] = 0; temp[VK_OEM_6] = 0; temp[VK_OEM_7] = 0; temp[VK_OEM_8] = 0; temp[VK_OEM_102] = 0; return temp; } static QHash intCharToQtKey() { QHash temp; temp.insert(QString('!'), Qt::Key_Exclam); temp.insert(QString('"'), Qt::Key_QuoteDbl); temp.insert(QString('#'), Qt::Key_NumberSign); temp.insert(QString('$'), Qt::Key_Dollar); temp.insert(QString('\''), Qt::Key_Apostrophe); temp.insert(QString('('), Qt::Key_ParenLeft); temp.insert(QString(')'), Qt::Key_ParenRight); temp.insert(QString('*'), Qt::Key_Asterisk); temp.insert(QString('+'), Qt::Key_Plus); temp.insert(QString(','), Qt::Key_Comma); temp.insert(QString('-'), Qt::Key_Minus); temp.insert(QString('.'), Qt::Key_Period); temp.insert(QString('/'), Qt::Key_Slash); temp.insert(QString(':'), Qt::Key_Colon); temp.insert(QString(';'), Qt::Key_Semicolon); temp.insert(QString('<'), Qt::Key_Less); temp.insert(QString('='), Qt::Key_Equal); temp.insert(QString('>'), Qt::Key_Greater); temp.insert(QString('@'), Qt::Key_At); temp.insert(QString('['), Qt::Key_BracketLeft); temp.insert(QString('\\'), Qt::Key_Backslash); temp.insert(QString(']'), Qt::Key_BracketRight); temp.insert(QString('^'), Qt::Key_AsciiCircum); temp.insert(QString('_'), Qt::Key_Underscore); temp.insert(QString('`'), Qt::Key_QuoteLeft); temp.insert(QString('{'), Qt::Key_BraceLeft); temp.insert(QString('}'), Qt::Key_BraceRight); temp.insert(QString::fromUtf8("\u00A1"), Qt::Key_exclamdown); temp.insert(QString('~'), Qt::Key_AsciiTilde); // temp.insert(QString::fromUtf8("\u20A0"), Qt::Key_) return temp; } static QHash initDeadKeyToQtKey() { QHash temp; // temp.insert(QString('`'), Qt::Key_Dead_Grave); // temp.insert(QString('\''), Qt::Key_Dead_Acute); temp.insert(QString::fromUtf8("\u00B4"), Qt::Key_Dead_Grave); // temp.insert(QString('^'), Qt::Key_Dead_Circumflex); // temp.insert(QString('~'), Qt::Key_Dead_Tilde); temp.insert(QString::fromUtf8("\u02DC"), Qt::Key_Dead_Tilde); temp.insert(QString::fromUtf8("\u00AF"), Qt::Key_Dead_Macron); temp.insert(QString::fromUtf8("\u02D8"), Qt::Key_Dead_Breve); temp.insert(QString::fromUtf8("\u02D9"), Qt::Key_Dead_Abovedot); // temp.insert(QString('"'), Qt::Key_Dead_Diaeresis); temp.insert(QString::fromUtf8("\u00A8"), Qt::Key_Dead_Diaeresis); temp.insert(QString::fromUtf8("\u02DA"), Qt::Key_Dead_Abovering); temp.insert(QString::fromUtf8("\u02DD"), Qt::Key_Dead_Doubleacute); temp.insert(QString::fromUtf8("\u02C7"), Qt::Key_Dead_Caron); // temp.insert(QString(','), Qt::Key_Dead_Cedilla); temp.insert(QString::fromUtf8("\u00B8"), Qt::Key_Dead_Cedilla); temp.insert(QString::fromUtf8("\u02DB"), Qt::Key_Dead_Ogonek); temp.insert(QString::fromUtf8("\u037A"), Qt::Key_Dead_Iota); temp.insert(QString::fromUtf8("\u309B"), Qt::Key_Dead_Voiced_Sound); temp.insert(QString::fromUtf8("\u309C"), Qt::Key_Dead_Semivoiced_Sound); return temp; } static QHash dynamicOEMToQtKeyHash = initDynamicKeyMapping(); static QHash charToQtKeyHash = intCharToQtKey(); static QHash deadKeyToQtKeyHash = initDeadKeyToQtKey(); QtWinKeyMapper::QtWinKeyMapper(QObject *parent) : QtKeyMapperBase(parent) { identifier = "sendinput"; populateMappingHashes(); populateCharKeyInformation(); } void QtWinKeyMapper::populateMappingHashes() { if (qtKeyToVirtKeyHash.isEmpty()) { qtKeyToVirtKeyHash[Qt::Key_Cancel] = VK_CANCEL; qtKeyToVirtKeyHash[Qt::Key_Backspace] = VK_BACK; qtKeyToVirtKeyHash[Qt::Key_Tab] = VK_TAB; qtKeyToVirtKeyHash[Qt::Key_Clear] = VK_CLEAR; qtKeyToVirtKeyHash[Qt::Key_Return] = VK_RETURN; qtKeyToVirtKeyHash[Qt::Key_Enter] = VK_RETURN; // qtKeyToWinVirtualKey[Qt::Key_Shift] = VK_SHIFT; // qtKeyToWinVirtualKey[Qt::Key_Control] = VK_CONTROL; // qtKeyToWinVirtualKey[Qt::Key_Alt] = VK_MENU; qtKeyToVirtKeyHash[Qt::Key_Pause] = VK_PAUSE; qtKeyToVirtKeyHash[Qt::Key_CapsLock] = VK_CAPITAL; qtKeyToVirtKeyHash[Qt::Key_Escape] = VK_ESCAPE; qtKeyToVirtKeyHash[Qt::Key_Mode_switch] = VK_MODECHANGE; qtKeyToVirtKeyHash[Qt::Key_Space] = VK_SPACE; qtKeyToVirtKeyHash[Qt::Key_PageUp] = VK_PRIOR; qtKeyToVirtKeyHash[Qt::Key_PageDown] = VK_NEXT; qtKeyToVirtKeyHash[Qt::Key_End] = VK_END; qtKeyToVirtKeyHash[Qt::Key_Home] = VK_HOME; qtKeyToVirtKeyHash[Qt::Key_Left] = VK_LEFT; qtKeyToVirtKeyHash[Qt::Key_Up] = VK_UP; qtKeyToVirtKeyHash[Qt::Key_Right] = VK_RIGHT; qtKeyToVirtKeyHash[Qt::Key_Down] = VK_DOWN; qtKeyToVirtKeyHash[Qt::Key_Select] = VK_SELECT; qtKeyToVirtKeyHash[Qt::Key_Printer] = VK_PRINT; qtKeyToVirtKeyHash[Qt::Key_Execute] = VK_EXECUTE; qtKeyToVirtKeyHash[Qt::Key_Print] = VK_SNAPSHOT; qtKeyToVirtKeyHash[Qt::Key_Insert] = VK_INSERT; qtKeyToVirtKeyHash[Qt::Key_Delete] = VK_DELETE; qtKeyToVirtKeyHash[Qt::Key_Help] = VK_HELP; qtKeyToVirtKeyHash[Qt::Key_Meta] = VK_LWIN; // qtKeyToWinVirtualKey[Qt::Key_Meta] = VK_RWIN; qtKeyToVirtKeyHash[Qt::Key_Menu] = VK_APPS; qtKeyToVirtKeyHash[Qt::Key_Sleep] = VK_SLEEP; qtKeyToVirtKeyHash[AntKey_KP_Multiply] = VK_MULTIPLY; // qtKeyToVirtKeyHash[Qt::Key_Asterisk] = VK_MULTIPLY; qtKeyToVirtKeyHash[AntKey_KP_Add] = VK_ADD; // qtKeyToVirtKeyHash[Qt::Key_Comma] = VK_SEPARATOR; qtKeyToVirtKeyHash[AntKey_KP_Subtract] = VK_SUBTRACT; qtKeyToVirtKeyHash[AntKey_KP_Decimal] = VK_DECIMAL; qtKeyToVirtKeyHash[AntKey_KP_Divide] = VK_DIVIDE; qtKeyToVirtKeyHash[Qt::Key_NumLock] = VK_NUMLOCK; qtKeyToVirtKeyHash[Qt::Key_ScrollLock] = VK_SCROLL; qtKeyToVirtKeyHash[Qt::Key_Massyo] = VK_OEM_FJ_MASSHOU; qtKeyToVirtKeyHash[Qt::Key_Touroku] = VK_OEM_FJ_TOUROKU; qtKeyToVirtKeyHash[Qt::Key_Shift] = VK_LSHIFT; // qtKeyToWinVirtualKey[Qt::Key_Shift] = VK_RSHIFT; qtKeyToVirtKeyHash[Qt::Key_Control] = VK_LCONTROL; // qtKeyToWinVirtualKey[Qt::Key_Control] = VK_RCONTROL; qtKeyToVirtKeyHash[Qt::Key_Alt] = VK_LMENU; // qtKeyToWinVirtualKey[Qt::Key_Alt] = VK_RMENU; qtKeyToVirtKeyHash[Qt::Key_Back] = VK_BROWSER_BACK; qtKeyToVirtKeyHash[Qt::Key_Forward] = VK_BROWSER_FORWARD; qtKeyToVirtKeyHash[Qt::Key_Refresh] = VK_BROWSER_REFRESH; qtKeyToVirtKeyHash[Qt::Key_Stop] = VK_BROWSER_STOP; qtKeyToVirtKeyHash[Qt::Key_Search] = VK_BROWSER_SEARCH; qtKeyToVirtKeyHash[Qt::Key_Favorites] = VK_BROWSER_FAVORITES; qtKeyToVirtKeyHash[Qt::Key_HomePage] = VK_BROWSER_HOME; qtKeyToVirtKeyHash[Qt::Key_VolumeMute] = VK_VOLUME_MUTE; qtKeyToVirtKeyHash[Qt::Key_VolumeDown] = VK_VOLUME_DOWN; qtKeyToVirtKeyHash[Qt::Key_VolumeUp] = VK_VOLUME_UP; qtKeyToVirtKeyHash[Qt::Key_MediaNext] = VK_MEDIA_NEXT_TRACK; qtKeyToVirtKeyHash[Qt::Key_MediaPrevious] = VK_MEDIA_PREV_TRACK; qtKeyToVirtKeyHash[Qt::Key_MediaStop] = VK_MEDIA_STOP; qtKeyToVirtKeyHash[Qt::Key_MediaPlay] = VK_MEDIA_PLAY_PAUSE; qtKeyToVirtKeyHash[Qt::Key_LaunchMail] = VK_LAUNCH_MAIL; qtKeyToVirtKeyHash[Qt::Key_LaunchMedia] = VK_LAUNCH_MEDIA_SELECT; qtKeyToVirtKeyHash[Qt::Key_Launch0] = VK_LAUNCH_APP1; qtKeyToVirtKeyHash[Qt::Key_Launch1] = VK_LAUNCH_APP2; qtKeyToVirtKeyHash[Qt::Key_Kanji] = VK_KANJI; // The following VK_OEM_* keys are consistent across all // keyboard layouts. qtKeyToVirtKeyHash[Qt::Key_Equal] = VK_OEM_PLUS; qtKeyToVirtKeyHash[Qt::Key_Minus] = VK_OEM_MINUS; qtKeyToVirtKeyHash[Qt::Key_Period] = VK_OEM_PERIOD; qtKeyToVirtKeyHash[Qt::Key_Comma] = VK_OEM_COMMA; /*qtKeyToVirtKeyHash[Qt::Key_Semicolon] = VK_OEM_1; qtKeyToVirtKeyHash[Qt::Key_Slash] = VK_OEM_2; qtKeyToVirtKeyHash[Qt::Key_Equal] = VK_OEM_PLUS; qtKeyToVirtKeyHash[Qt::Key_Minus] = VK_OEM_MINUS; qtKeyToVirtKeyHash[Qt::Key_Period] = VK_OEM_PERIOD; qtKeyToVirtKeyHash[Qt::Key_QuoteLeft] = VK_OEM_3; qtKeyToVirtKeyHash[Qt::Key_BracketLeft] = VK_OEM_4; qtKeyToVirtKeyHash[Qt::Key_Backslash] = VK_OEM_5; qtKeyToVirtKeyHash[Qt::Key_BracketRight] = VK_OEM_6; qtKeyToVirtKeyHash[Qt::Key_Apostrophe] = VK_OEM_7;*/ qtKeyToVirtKeyHash[Qt::Key_Play] = VK_PLAY; qtKeyToVirtKeyHash[Qt::Key_Zoom] = VK_ZOOM; // qtKeyToWinVirtualKey[Qt::Key_Clear] = VK_OEM_CLEAR; // Map 0-9 ASCII codes for (int i = 0; i <= (0x39 - 0x30); i++) { qtKeyToVirtKeyHash[Qt::Key_0 + i] = 0x30 + i; } // Map A-Z ASCII codes for (int i = 0; i <= (0x5a - 0x41); i++) { qtKeyToVirtKeyHash[Qt::Key_A + i] = 0x41 + i; } // Map function keys for (int i = 0; i <= (VK_F24 - VK_F1); i++) { qtKeyToVirtKeyHash[Qt::Key_F1 + i] = VK_F1 + i; } // Map numpad keys for (int i = 0; i <= (VK_NUMPAD9 - VK_NUMPAD0); i++) { qtKeyToVirtKeyHash[AntKey_KP_0 + i] = VK_NUMPAD0 + i; } // Map custom keys qtKeyToVirtKeyHash[AntKey_Alt_R] = VK_RMENU; qtKeyToVirtKeyHash[AntKey_Meta_R] = VK_RWIN; qtKeyToVirtKeyHash[AntKey_Shift_R] = VK_RSHIFT; qtKeyToVirtKeyHash[AntKey_Control_R] = VK_RCONTROL; // Go through VK_OEM_* values and find the appropriate association // with a key defined in Qt. Association is decided based on char // returned from Windows for the VK_OEM_* key. QHashIterator iterDynamic(dynamicOEMToQtKeyHash); while (iterDynamic.hasNext()) { iterDynamic.next(); byte ks[256]; char cbuf[2] = {'\0', '\0'}; GetKeyboardState(ks); unsigned int oemkey = iterDynamic.key(); unsigned int scancode = MapVirtualKey(oemkey, 0); int charlength = ToAscii(oemkey, scancode, ks, (WORD *)cbuf, 0); if (charlength < 0) { charlength = ToAscii(VK_SPACE, scancode, ks, (WORD *)cbuf, 0); QString temp = QString::fromUtf8(cbuf); if (temp.length() > 0) { QHashIterator tempiter(charToQtKeyHash); while (tempiter.hasNext()) { tempiter.next(); QString currentChar = tempiter.key(); if (currentChar == temp) { dynamicOEMToQtKeyHash[oemkey] = tempiter.value(); tempiter.toBack(); } } } } else if (charlength == 1) { QString temp = QString::fromUtf8(cbuf); QHashIterator tempiter(charToQtKeyHash); while (tempiter.hasNext()) { tempiter.next(); QString currentChar = tempiter.key(); if (currentChar == temp) { dynamicOEMToQtKeyHash[oemkey] = tempiter.value(); tempiter.toBack(); } } } } // Populate hash with values found for the VK_OEM_* keys. // Values will likely be different across various keyboard // layouts. iterDynamic = QHashIterator(dynamicOEMToQtKeyHash); while (iterDynamic.hasNext()) { iterDynamic.next(); unsigned int tempvalue = iterDynamic.value(); if (tempvalue != 0 && !qtKeyToVirtKeyHash.contains(tempvalue)) { qtKeyToVirtKeyHash.insert(tempvalue, iterDynamic.key()); } } // Populate other hash. Flip key and value so mapping // goes VK -> Qt Key. QHashIterator iter(qtKeyToVirtKeyHash); while (iter.hasNext()) { iter.next(); virtKeyToQtKeyHash[iter.value()] = iter.key(); } // Override current item for VK_RETURN virtKeyToQtKeyHash[VK_RETURN] = Qt::Key_Return; // Insert more aliases that would have resulted in // overwrites in other hash. virtKeyToQtKeyHash[VK_SHIFT] = Qt::Key_Shift; virtKeyToQtKeyHash[VK_CONTROL] = Qt::Key_Control; virtKeyToQtKeyHash[VK_MENU] = Qt::Key_Alt; } } int QtWinKeyMapper::returnQtKey(int key, int scancode) { int tempkey = virtKeyToQtKeyHash.value(key); int extended = scancode & WinExtras::EXTENDED_FLAG; if (key == VK_RETURN && extended) { tempkey = Qt::Key_Enter; } return tempkey; } void QtWinKeyMapper::populateCharKeyInformation() { virtkeyToCharKeyInfo.clear(); unsigned int total = 0; // BYTE ks[256]; // GetKeyboardState(ks); /*for (int x=0; x <= 255; x++) { if (ks[x] != 0) { qDebug() << "TEST: " << QString::number(x) << " | " << QString::number(ks[x]); } } */ for (int i = VK_SPACE; i <= VK_OEM_CLEAR; i++) { unsigned int scancode = MapVirtualKey(i, 0); for (int j = 0; j <= 3; j++) { WCHAR cbuf[256]; BYTE tempks[256]; memset(tempks, 0, sizeof(tempks)); Qt::KeyboardModifiers dicis; if (j >= 2) { dicis |= Qt::MetaModifier; tempks[VK_LWIN] = 1 << 7; // tempks[VK_RWIN] = 1 << 7; } if (j == 1 || j == 3) { dicis |= Qt::ShiftModifier; tempks[VK_LSHIFT] = 1 << 7; tempks[VK_SHIFT] = 1 << 7; // qDebug() << "NEVER ME: "; } int charlength = ToUnicode(i, scancode, tempks, cbuf, 255, 0); if (charlength == 1 || charlength < 0) { QString temp = QString::fromWCharArray(cbuf); if (temp.size() > 0) { QChar tempchar(temp.at(0)); charKeyInformation tempinfo; tempinfo.modifiers = dicis; tempinfo.virtualkey = i; if (!virtkeyToCharKeyInfo.contains(tempchar.unicode())) { virtkeyToCharKeyInfo.insert(tempchar.unicode(), tempinfo); total++; } } } } } qDebug() << "TOTAL: " << total; } AntiMicroX-antimicrox-b300273/src/qtwinkeymapper.h000066400000000000000000000023171471077622000221750ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef QTWINKEYMAPPER_H #define QTWINKEYMAPPER_H #include "qtkeymapperbase.h" class QtWinKeyMapper : public QtKeyMapperBase { Q_OBJECT public: explicit QtWinKeyMapper(QObject *parent = nullptr); virtual int returnQtKey(int key, int scancode = 0) override; protected: void populateMappingHashes() override; void populateCharKeyInformation() override; }; #endif // QTWINKEYMAPPER_H AntiMicroX-antimicrox-b300273/src/qtx11keymapper.cpp000066400000000000000000000413631471077622000223500ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define XK_MISCELLANY #define XK_LATIN1 #define XK_KOREAN #define XK_XKB_KEYS #include "qtx11keymapper.h" #include #include #include #include #include #include #include #include #include #include "x11extras.h" QtX11KeyMapper::QtX11KeyMapper(QObject *parent) : QtKeyMapperBase(parent) { identifier = "xtest"; populateMappingHashes(); populateCharKeyInformation(); } /* * The following mappings are mainly taken from qkeymapper_x11.cpp. * There are portions of the mapping that are customized to work around * some of the ambiguity introduced with some Qt keys * (XK_Alt_L and XK_Alt_R become Qt::Key_Alt in Qt). */ void QtX11KeyMapper::populateMappingHashes() { if (qtKeyToVirtKeyHash.isEmpty()) { mapMiscKeysQtX11(qtKeyToVirtKeyHash); mapCursorMovesKeysQtX11(qtKeyToVirtKeyHash); mapModifiersKeysQtX11(qtKeyToVirtKeyHash); mapAdditionalKeysQtX11(qtKeyToVirtKeyHash); mapKeypadKeysQtX11(qtKeyToVirtKeyHash); mapInternationKeysQtX11(qtKeyToVirtKeyHash); // Misc Functions qtKeyToVirtKeyHash[Qt::Key_Mode_switch] = XK_Mode_switch; // qtKeyToX11KeySym[Qt::Key_Mode_switch] = XK_script_switch; mapJapanKeysQtX11(qtKeyToVirtKeyHash); #ifdef XK_KOREAN mapKoreanKeysQtX11(qtKeyToVirtKeyHash); #endif // XK_KOREAN mapDeadKeysQtX11(qtKeyToVirtKeyHash); mapBrowseKeysQtX11(qtKeyToVirtKeyHash); mapMediaKeysQtX11(qtKeyToVirtKeyHash); mapLaunchKeysQtX11(qtKeyToVirtKeyHash); // Map initial ASCII keys for (int i = 0; i <= (XK_at - XK_space); i++) qtKeyToVirtKeyHash[Qt::Key_Space + i] = XK_space + i; // Map lowercase alpha keys for (int i = 0; i <= (XK_z - XK_a); i++) qtKeyToVirtKeyHash[Qt::Key_A + i] = XK_a + i; // Map [ to ` ASCII keys for (int i = 0; i <= (XK_grave - XK_bracketleft); i++) qtKeyToVirtKeyHash[Qt::Key_BracketLeft + i] = XK_bracketleft + i; // Map { to ~ ASCII keys for (int i = 0; i <= (XK_asciitilde - XK_braceleft); i++) qtKeyToVirtKeyHash[Qt::Key_BraceLeft + i] = XK_braceleft + i; // Map function keys for (int i = 0; i <= (XK_F35 - XK_F1); i++) qtKeyToVirtKeyHash[Qt::Key_F1 + i] = XK_F1 + i; // Misc // qtKeyToVirtKeyHash[Qt::KeyBri] // Map custom defined keys qtKeyToVirtKeyHash[AntKey_Shift_R] = XK_Shift_R; qtKeyToVirtKeyHash[AntKey_Control_R] = XK_Control_R; // qtKeyToX11KeySym[AntKey_Shift_Lock] = XK_Shift_Lock; // qtKeyToVirtKeyHash[AntKey_Meta_R] = XK_Meta_R; qtKeyToVirtKeyHash[AntKey_Alt_R] = XK_Alt_R; qtKeyToVirtKeyHash[AntKey_KP_Multiply] = XK_KP_Multiply; // Map 0 to 9 for (int i = 0; i <= (XK_KP_9 - XK_KP_0); i++) qtKeyToVirtKeyHash[AntKey_KP_0 + i] = XK_KP_0 + i; // Map lower-case latin characters to their capital equivalents for (int i = 0; i <= (XK_odiaeresis - XK_agrave); i++) qtKeyToVirtKeyHash[Qt::Key_Agrave + i] = XK_agrave + i; for (int i = 0; i <= (XK_thorn - XK_oslash); i++) qtKeyToVirtKeyHash[Qt::Key_Ooblique + i] = XK_oslash + i; QHashIterator iter(qtKeyToVirtKeyHash); while (iter.hasNext()) { iter.next(); virtKeyToQtKeyHash[iter.value()] = iter.key(); } } } void QtX11KeyMapper::populateCharKeyInformation() { virtkeyToCharKeyInfo.clear(); Display *display = X11Extras::getInstance()->display(); int total = 0; for (int i = 8; i <= 255; i++) { for (int j = 0; j <= 3; j++) { Qt::KeyboardModifiers dicis; if (j >= 2) dicis |= Qt::MetaModifier; if ((j == 1) || (j == 3)) dicis |= Qt::ShiftModifier; int testsym = XkbKeycodeToKeysym(display, i, (dicis & Qt::MetaModifier) ? 1 : 0, (dicis & Qt::ShiftModifier) ? 1 : 0); if (testsym != NoSymbol) { XKeyPressedEvent tempevent; tempevent.keycode = i; tempevent.type = KeyPress; tempevent.display = display; tempevent.state = 0; if (dicis & Qt::ShiftModifier) tempevent.state |= ShiftMask; if (dicis & Qt::MetaModifier) tempevent.state |= Mod1Mask; char returnstring[256]; memset(returnstring, 0, sizeof(returnstring)); int bitestoreturn = sizeof(returnstring) - 1; int numchars = XLookupString(&tempevent, returnstring, bitestoreturn, nullptr, nullptr); if (numchars > 0) { returnstring[numchars] = '\0'; QString tempstring = QString::fromUtf8(returnstring); if (tempstring.length() == 1) { QChar tempchar(tempstring.at(0)); charKeyInformation testKeyInformation; testKeyInformation.modifiers = dicis; testKeyInformation.virtualkey = testsym; if (!virtkeyToCharKeyInfo.contains(tempchar.unicode())) { virtkeyToCharKeyInfo.insert(tempchar.unicode(), testKeyInformation); total++; } } } } } } qDebug() << "TOTAL: " << total; } void QtX11KeyMapper::mapMiscKeysQtX11(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_Escape] = XK_Escape; qtKeyToVirtKeyHash[Qt::Key_Tab] = XK_Tab; qtKeyToVirtKeyHash[Qt::Key_Backtab] = XK_ISO_Left_Tab; qtKeyToVirtKeyHash[Qt::Key_Backspace] = XK_BackSpace; qtKeyToVirtKeyHash[Qt::Key_Return] = XK_Return; qtKeyToVirtKeyHash[Qt::Key_Insert] = XK_Insert; qtKeyToVirtKeyHash[Qt::Key_Delete] = XK_Delete; // qtKeyToX11KeySym[Qt::Key_Delete] = XK_Clear; qtKeyToVirtKeyHash[Qt::Key_Pause] = XK_Pause; qtKeyToVirtKeyHash[Qt::Key_Print] = XK_Print; } void QtX11KeyMapper::mapCursorMovesKeysQtX11(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_Home] = XK_Home; qtKeyToVirtKeyHash[Qt::Key_End] = XK_End; qtKeyToVirtKeyHash[Qt::Key_Left] = XK_Left; qtKeyToVirtKeyHash[Qt::Key_Up] = XK_Up; qtKeyToVirtKeyHash[Qt::Key_Right] = XK_Right; qtKeyToVirtKeyHash[Qt::Key_Down] = XK_Down; qtKeyToVirtKeyHash[Qt::Key_PageUp] = XK_Prior; qtKeyToVirtKeyHash[Qt::Key_PageDown] = XK_Next; } void QtX11KeyMapper::mapModifiersKeysQtX11(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_Shift] = XK_Shift_L; // qtKeyToX11KeySym[Qt::Key_Shift] = XK_Shift_R; // qtKeyToX11KeySym[Qt::Key_Shift] = XK_Shift_Lock; qtKeyToVirtKeyHash[Qt::Key_Control] = XK_Control_L; // qtKeyToX11KeySym[Qt::Key_Control] = XK_Control_R; // qtKeyToVirtKeyHash[Qt::Key_Meta] = XK_Meta_L; // qtKeyToX11KeySym[Qt::Key_Meta] = XK_Meta_R; qtKeyToVirtKeyHash[Qt::Key_Alt] = XK_Alt_L; // qtKeyToX11KeySym[Qt::Key_Alt] = XK_Alt_R; } void QtX11KeyMapper::mapAdditionalKeysQtX11(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_CapsLock] = XK_Caps_Lock; qtKeyToVirtKeyHash[Qt::Key_NumLock] = XK_Num_Lock; qtKeyToVirtKeyHash[Qt::Key_ScrollLock] = XK_Scroll_Lock; qtKeyToVirtKeyHash[Qt::Key_Meta] = XK_Super_L; qtKeyToVirtKeyHash[AntKey_Meta_R] = XK_Super_R; // qtKeyToVirtKeyHash[Qt::Key_Super_L] = XK_Super_L; // qtKeyToVirtKeyHash[Qt::Key_Super_R] = XK_Super_R; qtKeyToVirtKeyHash[Qt::Key_Menu] = XK_Menu; qtKeyToVirtKeyHash[Qt::Key_Hyper_L] = XK_Hyper_L; qtKeyToVirtKeyHash[Qt::Key_Hyper_R] = XK_Hyper_R; qtKeyToVirtKeyHash[Qt::Key_Help] = XK_Help; } void QtX11KeyMapper::mapKeypadKeysQtX11(QHash &qtKeyToVirtKeyHash) { // qtKeyToVirtKeyHash[Qt::Key_Space] = XK_KP_Space; // qtKeyToX11KeySym[Qt::Key_Tab] = XK_KP_Tab; qtKeyToVirtKeyHash[AntKey_KP_Enter] = XK_KP_Enter; qtKeyToVirtKeyHash[AntKey_KP_Home] = XK_KP_Home; // qtKeyToX11KeySym[Qt::Key_Home] = XK_KP_Home; qtKeyToVirtKeyHash[AntKey_KP_Left] = XK_KP_Left; qtKeyToVirtKeyHash[AntKey_KP_Up] = XK_KP_Up; qtKeyToVirtKeyHash[AntKey_KP_Right] = XK_KP_Right; qtKeyToVirtKeyHash[AntKey_KP_Down] = XK_KP_Down; qtKeyToVirtKeyHash[AntKey_KP_Prior] = XK_KP_Prior; qtKeyToVirtKeyHash[AntKey_KP_Next] = XK_KP_Next; qtKeyToVirtKeyHash[AntKey_KP_End] = XK_KP_End; qtKeyToVirtKeyHash[AntKey_KP_Begin] = XK_KP_Begin; qtKeyToVirtKeyHash[AntKey_KP_Insert] = XK_KP_Insert; qtKeyToVirtKeyHash[AntKey_KP_Delete] = XK_KP_Delete; // qtKeyToX11KeySym[AntKey_KP_Equal] = XK_KP_Equal; qtKeyToVirtKeyHash[AntKey_KP_Add] = XK_KP_Add; // qtKeyToX11KeySym[AntKey_KP_Separator] = XK_KP_Separator; qtKeyToVirtKeyHash[AntKey_KP_Subtract] = XK_KP_Subtract; qtKeyToVirtKeyHash[AntKey_KP_Decimal] = XK_KP_Decimal; qtKeyToVirtKeyHash[AntKey_KP_Divide] = XK_KP_Divide; qtKeyToVirtKeyHash[AntKey_KP_1] = XK_KP_1; qtKeyToVirtKeyHash[AntKey_KP_2] = XK_KP_2; qtKeyToVirtKeyHash[AntKey_KP_3] = XK_KP_3; qtKeyToVirtKeyHash[AntKey_KP_4] = XK_KP_4; qtKeyToVirtKeyHash[AntKey_KP_5] = XK_KP_5; qtKeyToVirtKeyHash[AntKey_KP_6] = XK_KP_6; qtKeyToVirtKeyHash[AntKey_KP_7] = XK_KP_7; qtKeyToVirtKeyHash[AntKey_KP_8] = XK_KP_8; qtKeyToVirtKeyHash[AntKey_KP_9] = XK_KP_9; qtKeyToVirtKeyHash[AntKey_KP_0] = XK_KP_0; } void QtX11KeyMapper::mapInternationKeysQtX11(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_AltGr] = XK_ISO_Level3_Shift; qtKeyToVirtKeyHash[Qt::Key_Multi_key] = XK_Multi_key; qtKeyToVirtKeyHash[Qt::Key_Codeinput] = XK_Codeinput; qtKeyToVirtKeyHash[Qt::Key_SingleCandidate] = XK_SingleCandidate; qtKeyToVirtKeyHash[Qt::Key_MultipleCandidate] = XK_MultipleCandidate; qtKeyToVirtKeyHash[Qt::Key_PreviousCandidate] = XK_PreviousCandidate; } void QtX11KeyMapper::mapJapanKeysQtX11(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_Kanji] = XK_Kanji; qtKeyToVirtKeyHash[Qt::Key_Muhenkan] = XK_Muhenkan; qtKeyToVirtKeyHash[Qt::Key_Henkan] = XK_Henkan_Mode; // qtKeyToX11KeySym[Qt::Key_Henkan] = XK_Henkan; qtKeyToVirtKeyHash[Qt::Key_Romaji] = XK_Romaji; qtKeyToVirtKeyHash[Qt::Key_Hiragana] = XK_Hiragana; qtKeyToVirtKeyHash[Qt::Key_Katakana] = XK_Katakana; qtKeyToVirtKeyHash[Qt::Key_Hiragana_Katakana] = XK_Hiragana_Katakana; qtKeyToVirtKeyHash[Qt::Key_Zenkaku] = XK_Zenkaku; qtKeyToVirtKeyHash[Qt::Key_Hankaku] = XK_Hankaku; qtKeyToVirtKeyHash[Qt::Key_Zenkaku_Hankaku] = XK_Zenkaku_Hankaku; qtKeyToVirtKeyHash[Qt::Key_Touroku] = XK_Touroku; qtKeyToVirtKeyHash[Qt::Key_Massyo] = XK_Massyo; qtKeyToVirtKeyHash[Qt::Key_Kana_Lock] = XK_Kana_Lock; qtKeyToVirtKeyHash[Qt::Key_Kana_Shift] = XK_Kana_Shift; qtKeyToVirtKeyHash[Qt::Key_Eisu_Shift] = XK_Eisu_Shift; qtKeyToVirtKeyHash[Qt::Key_Eisu_toggle] = XK_Eisu_toggle; qtKeyToVirtKeyHash[Qt::Key_Codeinput] = XK_Kanji_Bangou; // qtKeyToX11KeySym[Qt::Key_MultipleCandidate] = XK_Zen_Koho; // qtKeyToX11KeySym[Qt::Key_PreviousCandidate] = XK_Mae_Koho; } void QtX11KeyMapper::mapKoreanKeysQtX11(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_Hangul] = XK_Hangul; qtKeyToVirtKeyHash[Qt::Key_Hangul_Start] = XK_Hangul_Start; qtKeyToVirtKeyHash[Qt::Key_Hangul_End] = XK_Hangul_End; qtKeyToVirtKeyHash[Qt::Key_Hangul_Hanja] = XK_Hangul_Hanja; qtKeyToVirtKeyHash[Qt::Key_Hangul_Jamo] = XK_Hangul_Jamo; qtKeyToVirtKeyHash[Qt::Key_Hangul_Romaja] = XK_Hangul_Romaja; // qtKeyToX11KeySym[Qt::Key_Codeinput] = XK_Hangul_Codeinput; qtKeyToVirtKeyHash[Qt::Key_Hangul_Jeonja] = XK_Hangul_Jeonja; qtKeyToVirtKeyHash[Qt::Key_Hangul_Banja] = XK_Hangul_Banja; qtKeyToVirtKeyHash[Qt::Key_Hangul_PreHanja] = XK_Hangul_PreHanja; qtKeyToVirtKeyHash[Qt::Key_Hangul_PostHanja] = XK_Hangul_PostHanja; // qtKeyToX11KeySym[Qt::Key_SingleCandidate] = XK_Hangul_SingleCandidate; // qtKeyToX11KeySym[Qt::Key_MultipleCandidate] = XK_Hangul_MultipleCandidate; // qtKeyToX11KeySym[Qt::Key_PreviousCandidate] = XK_Hangul_PreviousCandidate; qtKeyToVirtKeyHash[Qt::Key_Hangul_Special] = XK_Hangul_Special; // qtKeyToX11KeySym[Qt::Key_Mode_switch] = XK_Hangul_switch; } void QtX11KeyMapper::mapDeadKeysQtX11(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_Dead_Grave] = XK_dead_grave; qtKeyToVirtKeyHash[Qt::Key_Dead_Acute] = XK_dead_acute; qtKeyToVirtKeyHash[Qt::Key_Dead_Circumflex] = XK_dead_circumflex; qtKeyToVirtKeyHash[Qt::Key_Dead_Tilde] = XK_dead_tilde; qtKeyToVirtKeyHash[Qt::Key_Dead_Macron] = XK_dead_macron; qtKeyToVirtKeyHash[Qt::Key_Dead_Breve] = XK_dead_breve; qtKeyToVirtKeyHash[Qt::Key_Dead_Abovedot] = XK_dead_abovedot; qtKeyToVirtKeyHash[Qt::Key_Dead_Diaeresis] = XK_dead_diaeresis; qtKeyToVirtKeyHash[Qt::Key_Dead_Abovering] = XK_dead_abovering; qtKeyToVirtKeyHash[Qt::Key_Dead_Doubleacute] = XK_dead_doubleacute; qtKeyToVirtKeyHash[Qt::Key_Dead_Caron] = XK_dead_caron; qtKeyToVirtKeyHash[Qt::Key_Dead_Cedilla] = XK_dead_cedilla; qtKeyToVirtKeyHash[Qt::Key_Dead_Ogonek] = XK_dead_ogonek; qtKeyToVirtKeyHash[Qt::Key_Dead_Iota] = XK_dead_iota; qtKeyToVirtKeyHash[Qt::Key_Dead_Voiced_Sound] = XK_dead_voiced_sound; qtKeyToVirtKeyHash[Qt::Key_Dead_Semivoiced_Sound] = XK_dead_semivoiced_sound; qtKeyToVirtKeyHash[Qt::Key_Dead_Belowdot] = XK_dead_belowdot; qtKeyToVirtKeyHash[Qt::Key_Dead_Hook] = XK_dead_hook; qtKeyToVirtKeyHash[Qt::Key_Dead_Horn] = XK_dead_horn; } void QtX11KeyMapper::mapBrowseKeysQtX11(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_Back] = XF86XK_Back; qtKeyToVirtKeyHash[Qt::Key_Forward] = XF86XK_Forward; qtKeyToVirtKeyHash[Qt::Key_Stop] = XF86XK_Stop; qtKeyToVirtKeyHash[Qt::Key_Refresh] = XF86XK_Refresh; qtKeyToVirtKeyHash[Qt::Key_Favorites] = XF86XK_Favorites; qtKeyToVirtKeyHash[Qt::Key_LaunchMedia] = XF86XK_AudioMedia; qtKeyToVirtKeyHash[Qt::Key_OpenUrl] = XF86XK_OpenURL; qtKeyToVirtKeyHash[Qt::Key_HomePage] = XF86XK_HomePage; qtKeyToVirtKeyHash[Qt::Key_Search] = XF86XK_Search; } void QtX11KeyMapper::mapMediaKeysQtX11(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_VolumeDown] = XF86XK_AudioLowerVolume; qtKeyToVirtKeyHash[Qt::Key_VolumeMute] = XF86XK_AudioMute; qtKeyToVirtKeyHash[Qt::Key_VolumeUp] = XF86XK_AudioRaiseVolume; qtKeyToVirtKeyHash[Qt::Key_MediaPlay] = XF86XK_AudioPlay; qtKeyToVirtKeyHash[Qt::Key_MediaStop] = XF86XK_AudioStop; qtKeyToVirtKeyHash[Qt::Key_MediaPrevious] = XF86XK_AudioPrev; qtKeyToVirtKeyHash[Qt::Key_MediaNext] = XF86XK_AudioNext; qtKeyToVirtKeyHash[Qt::Key_MediaRecord] = XF86XK_AudioRecord; } void QtX11KeyMapper::mapLaunchKeysQtX11(QHash &qtKeyToVirtKeyHash) { qtKeyToVirtKeyHash[Qt::Key_LaunchMail] = XF86XK_Mail; qtKeyToVirtKeyHash[Qt::Key_Launch0] = XF86XK_MyComputer; qtKeyToVirtKeyHash[Qt::Key_Launch1] = XF86XK_Calculator; qtKeyToVirtKeyHash[Qt::Key_Standby] = XF86XK_Standby; qtKeyToVirtKeyHash[Qt::Key_Launch2] = XF86XK_Launch0; qtKeyToVirtKeyHash[Qt::Key_Launch3] = XF86XK_Launch1; qtKeyToVirtKeyHash[Qt::Key_Launch4] = XF86XK_Launch2; qtKeyToVirtKeyHash[Qt::Key_Launch5] = XF86XK_Launch3; qtKeyToVirtKeyHash[Qt::Key_Launch6] = XF86XK_Launch4; qtKeyToVirtKeyHash[Qt::Key_Launch7] = XF86XK_Launch5; qtKeyToVirtKeyHash[Qt::Key_Launch8] = XF86XK_Launch6; qtKeyToVirtKeyHash[Qt::Key_Launch9] = XF86XK_Launch7; qtKeyToVirtKeyHash[Qt::Key_LaunchA] = XF86XK_Launch8; qtKeyToVirtKeyHash[Qt::Key_LaunchB] = XF86XK_Launch9; qtKeyToVirtKeyHash[Qt::Key_LaunchC] = XF86XK_LaunchA; qtKeyToVirtKeyHash[Qt::Key_LaunchD] = XF86XK_LaunchB; qtKeyToVirtKeyHash[Qt::Key_LaunchE] = XF86XK_LaunchC; qtKeyToVirtKeyHash[Qt::Key_LaunchF] = XF86XK_LaunchD; } AntiMicroX-antimicrox-b300273/src/qtx11keymapper.h000066400000000000000000000036741471077622000220200ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef QTX11KEYMAPPER_H #define QTX11KEYMAPPER_H #include "qtkeymapperbase.h" class QtX11KeyMapper : public QtKeyMapperBase { Q_OBJECT public: explicit QtX11KeyMapper(QObject *parent = nullptr); protected: void populateMappingHashes() override; void populateCharKeyInformation() override; private: void mapMiscKeysQtX11(QHash &qtKeyToVirtKeyHash); void mapCursorMovesKeysQtX11(QHash &qtKeyToVirtKeyHash); void mapModifiersKeysQtX11(QHash &qtKeyToVirtKeyHash); void mapAdditionalKeysQtX11(QHash &qtKeyToVirtKeyHash); void mapKeypadKeysQtX11(QHash &qtKeyToVirtKeyHash); void mapInternationKeysQtX11(QHash &qtKeyToVirtKeyHash); void mapJapanKeysQtX11(QHash &qtKeyToVirtKeyHash); void mapKoreanKeysQtX11(QHash &qtKeyToVirtKeyHash); void mapDeadKeysQtX11(QHash &qtKeyToVirtKeyHash); void mapBrowseKeysQtX11(QHash &qtKeyToVirtKeyHash); void mapMediaKeysQtX11(QHash &qtKeyToVirtKeyHash); void mapLaunchKeysQtX11(QHash &qtKeyToVirtKeyHash); }; #endif // QTX11KEYMAPPER_H AntiMicroX-antimicrox-b300273/src/resources.qrc000066400000000000000000000051221471077622000214620ustar00rootroot00000000000000 images/antimicrox.png images/axis.png images/button.png images/controllermap.svg images/actions/wiki.png images/actions/about_qt.png images/actions/about_antimicrox.png images/actions/github_page.png images/actions/issues.png images/actions/settings.png images/actions/stick_pad_assign.png images/actions/calibration.png images/actions/map_controller.png images/actions/sliders.png images/actions/key_checker.png images/actions/application_exit.png images/actions/archive_insert.png images/actions/dialog_cancel.png images/actions/dialog_close.png images/actions/dialog_ok.png images/actions/document_close.png images/actions/document_open.png images/actions/document_open_folder.png images/actions/document_revert.png images/actions/document_revert_small.png images/actions/document_save.png images/actions/document_save_as.png images/actions/edit_clear.png images/actions/edit_clear_list.png images/actions/edit_delete.png images/actions/edit_select.png images/actions/edit_table_delete_row.png images/actions/edit_table_insert_row_below.png images/actions/games_config_custom.png images/actions/games_config_options.png images/actions/help_about.png images/actions/text_field.png images/actions/view_fullscreen.png images/actions/view_refresh.png images/actions/view_restore.png images/actions/battery-empty.png images/actions/battery-full.png images/actions/battery-good-charging.png images/actions/battery-good.png images/actions/battery-low.png images/battery-low-level.png images/actions/join_slots.png images/actions/split_slot.png CHANGELOG.md AntiMicroX-antimicrox-b300273/src/sdleventreader.cpp000066400000000000000000000151661471077622000224650ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "sdleventreader.h" #include "antimicrosettings.h" #include "common.h" #include "globalvariables.h" #include "inputdevice.h" //#include "logger.h" #include #include #include #include #include SDLEventReader::SDLEventReader(QMap *joysticks, AntiMicroSettings *settings, QObject *parent) : QObject(parent) { this->joysticks = joysticks; this->settings = settings; settings->getLock()->lock(); this->pollRate = settings->value("GamepadPollRate", GlobalVariables::AntimicroSettings::defaultSDLGamepadPollRate).toUInt(); settings->getLock()->unlock(); pollRateTimer.setParent(this); pollRateTimer.setTimerType(Qt::PreciseTimer); initSDL(); connect(&pollRateTimer, &QTimer::timeout, this, &SDLEventReader::performWork); } SDLEventReader::~SDLEventReader() { if (sdlIsOpen) { closeSDL(); } } void SDLEventReader::initSDL() { // SDL_INIT_GAMECONTROLLER should automatically initialize SDL_INIT_JOYSTICK // but it doesn't seem to be the case with v2.0.4 // Passing SDL_INIT_SENSOR here triggers bug libsdl-org/SDL#4276 on windows // with v2.0.20. However, sensors works without in Linux and Windows so // skip it. //#if SDL_VERSION_ATLEAST(2, 0, 14) // SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK | SDL_INIT_SENSOR); //#else SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK); //#endif SDL_JoystickEventState(SDL_ENABLE); sdlIsOpen = true; loadSdlMappingsFromDatabase(); settings->getLock()->lock(); settings->beginGroup("Mappings"); QStringList mappings = settings->allKeys(); for (auto &&tempstring : mappings) { QString mappingSetting = settings->value(tempstring, QString()).toString(); if (!mappingSetting.isEmpty()) { QByteArray temparray = mappingSetting.toUtf8(); char *mapping = temparray.data(); SDL_GameControllerAddMapping(mapping); // Let SDL take care of validation } } settings->endGroup(); settings->getLock()->unlock(); pollRateTimer.stop(); pollRateTimer.setInterval(pollRate); emit sdlStarted(); } void SDLEventReader::closeSDL() { pollRateTimer.stop(); SDL_Event event; closeDevices(); // Clear any pending events while (SDL_PollEvent(&event) > 0) { } SDL_Quit(); sdlIsOpen = false; emit sdlClosed(); } void SDLEventReader::performWork() { if (sdlIsOpen && (eventStatus() > 0)) { pollRateTimer.stop(); emit eventRaised(); } } void SDLEventReader::stop() { if (sdlIsOpen) { SDL_Event event; event.type = SDL_QUIT; SDL_PushEvent(&event); } pollRateTimer.stop(); } void SDLEventReader::refresh() { if (sdlIsOpen) { stop(); QTimer::singleShot(0, this, SLOT(secondaryRefresh())); } } void SDLEventReader::secondaryRefresh() { if (sdlIsOpen) closeSDL(); initSDL(); } void SDLEventReader::clearEvents() { if (sdlIsOpen) { SDL_Event event; while (SDL_PollEvent(&event) > 0) { } } } bool SDLEventReader::isSDLOpen() { return sdlIsOpen; } int SDLEventReader::eventStatus() { int result = 0; SDL_PumpEvents(); switch (SDL_PeepEvents(nullptr, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) { case -1: { qCritical() << QString("SDL Error: %1").arg(QString(SDL_GetError())); result = 0; break; } case 0: { if (!pollRateTimer.isActive()) pollRateTimer.start(); break; } default: { result = 1; break; } } return result; } void SDLEventReader::updatePollRate(int tempPollRate) { if ((tempPollRate >= 1) && (tempPollRate <= 16)) { bool pollTimerWasActive = pollRateTimer.isActive(); pollRateTimer.stop(); this->pollRate = tempPollRate; pollRateTimer.setInterval(pollRate); if (pollTimerWasActive) pollRateTimer.start(); } } void SDLEventReader::resetJoystickMap() { joysticks = nullptr; } void SDLEventReader::quit() { if (sdlIsOpen) { closeSDL(); joysticks = nullptr; } } void SDLEventReader::closeDevices() { if (sdlIsOpen && (joysticks != nullptr)) { QMapIterator iter(*joysticks); while (iter.hasNext()) { iter.next(); InputDevice *current = iter.value(); current->closeSDLDevice(); } } } /** * @brief Method to block activity on the SDLEventReader object and its thread * event loop. */ void SDLEventReader::haltServices() { PadderCommon::lockInputDevices(); PadderCommon::unlockInputDevices(); } /** * @brief Loading additional gamepad mappings from database * */ void SDLEventReader::loadSdlMappingsFromDatabase() { QString database_file; database_file = QApplication::applicationDirPath().append("/../share/antimicrox/gamecontrollerdb.txt"); if (QFile::exists(database_file)) { int result = SDL_GameControllerAddMappingsFromFile(database_file.toStdString().c_str()); if (result == -1) qWarning() << "Loading game controller mappings from database: " << database_file << " failed"; else DEBUG() << "Loaded " << result << " game controller mappings from database"; } #ifndef QT_DEBUG else { qWarning() << "File with game controller mappings " << database_file << " does not exist"; } #endif } QMap *SDLEventReader::getJoysticks() const { return joysticks; } AntiMicroSettings *SDLEventReader::getSettings() const { return settings; } QTimer const &SDLEventReader::getPollRateTimer() { return pollRateTimer; } AntiMicroX-antimicrox-b300273/src/sdleventreader.h000066400000000000000000000040271471077622000221240ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SDLEVENTREADER_H #define SDLEVENTREADER_H #include "joystick.h" class InputDevice; class AntiMicroSettings; class SDLEventReader : public QObject { Q_OBJECT public: explicit SDLEventReader(QMap *joysticks, AntiMicroSettings *settings, QObject *parent = nullptr); ~SDLEventReader(); bool isSDLOpen(); QMap *getJoysticks() const; AntiMicroSettings *getSettings() const; QTimer const &getPollRateTimer(); protected: void initSDL(); void closeSDL(); void clearEvents(); int eventStatus(); signals: void eventRaised(); void finished(); void sdlStarted(); void sdlClosed(); public slots: void performWork(); void stop(); void refresh(); void updatePollRate(int tempPollRate); // (unsigned) void resetJoystickMap(); void quit(); void closeDevices(); void haltServices(); private slots: void secondaryRefresh(); private: QMap *joysticks; bool sdlIsOpen; AntiMicroSettings *settings; int pollRate; QTimer pollRateTimer; void loadSdlMappingsFromDatabase(); }; #endif // SDLEVENTREADER_H AntiMicroX-antimicrox-b300273/src/sensorpushbuttongroup.cpp000066400000000000000000000102371471077622000241720ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "sensorpushbuttongroup.h" #include "buttoneditdialog.h" #include "inputdevice.h" #include "joybuttontypes/joysensorbutton.h" #include "joysensor.h" #include "joysensorbuttonpushbutton.h" #include "joysensoreditdialog.h" #include "joysensorpushbutton.h" #include #include #include SensorPushButtonGroup::SensorPushButtonGroup(JoySensor *sensor, bool keypadUnlocked, bool displayNames, QWidget *parent) : QGridLayout(parent) , m_sensor(sensor) , m_display_names(displayNames) , m_keypad_unlocked(keypadUnlocked) { m_left_button = generateBtnToGrid(SENSOR_LEFT, 1, 0); m_right_button = generateBtnToGrid(SENSOR_RIGHT, 1, 2); m_up_button = generateBtnToGrid(SENSOR_UP, 0, 1); m_down_button = generateBtnToGrid(SENSOR_DOWN, 2, 1); m_bwd_button = generateBtnToGrid(SENSOR_BWD, 0, 2); if (m_sensor->getType() == GYROSCOPE) m_fwd_button = generateBtnToGrid(SENSOR_FWD, 2, 0); else m_fwd_button = nullptr; m_sensor_widget = new JoySensorPushButton(m_sensor, m_display_names, parentWidget()); m_sensor_widget->setIcon( QIcon::fromTheme(QString::fromUtf8("games_config_options"), QIcon(":/images/actions/games_config_options.png"))); connect(m_sensor_widget, &JoySensorPushButton::clicked, this, &SensorPushButtonGroup::showSensorDialog); addWidget(m_sensor_widget, 1, 1); } /** * @brief Generates a new push button at the given grid coordinates * @returns Newly created push button */ JoySensorButtonPushButton *SensorPushButtonGroup::generateBtnToGrid(JoySensorDirection sensorDir, int gridRow, int gridCol) { JoySensorButton *button = m_sensor->getButtons()->value(sensorDir); JoySensorButtonPushButton *pushbutton = new JoySensorButtonPushButton(button, m_display_names, parentWidget()); connect(pushbutton, &JoySensorButtonPushButton::clicked, this, [this, pushbutton] { openSensorButtonDialog(pushbutton); }); button->establishPropertyUpdatedConnections(); connect(button, &JoySensorButton::slotsChanged, this, &SensorPushButtonGroup::propagateSlotsChanged); addWidget(pushbutton, gridRow, gridCol); return pushbutton; } void SensorPushButtonGroup::propagateSlotsChanged() { emit buttonSlotChanged(); } /** * @brief Get the underlying JoySensor object. */ JoySensor *SensorPushButtonGroup::getSensor() const { return m_sensor; } /** * @brief Shows the button mapping dialog for the given direction button */ void SensorPushButtonGroup::openSensorButtonDialog(JoySensorButtonPushButton *pushbutton) { ButtonEditDialog *dialog = new ButtonEditDialog(pushbutton->getButton(), m_sensor->getParentSet()->getInputDevice(), m_keypad_unlocked, parentWidget()); dialog->show(); } /** * @brief Shows the sensor settings dialog */ void SensorPushButtonGroup::showSensorDialog() { JoySensorEditDialog *dialog = new JoySensorEditDialog(m_sensor, parentWidget()); dialog->show(); } void SensorPushButtonGroup::toggleNameDisplay() { m_display_names = !m_display_names; m_up_button->toggleNameDisplay(); m_down_button->toggleNameDisplay(); m_left_button->toggleNameDisplay(); m_right_button->toggleNameDisplay(); m_bwd_button->toggleNameDisplay(); if (m_fwd_button != nullptr) m_fwd_button->toggleNameDisplay(); m_sensor_widget->toggleNameDisplay(); } bool SensorPushButtonGroup::ifDisplayNames() const { return m_display_names; } AntiMicroX-antimicrox-b300273/src/sensorpushbuttongroup.h000066400000000000000000000041461471077622000236410ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "joysensordirection.h" #include class JoySensor; class QWidget; class JoySensorButtonPushButton; class JoySensorPushButton; /** * @brief The sensor button mapping widget in the main window. * The layout is based on a isometric 3D view with the regular * XY axes and a diagonal Z axis. */ class SensorPushButtonGroup : public QGridLayout { Q_OBJECT public: explicit SensorPushButtonGroup(JoySensor *sensor, bool keypadUnlocked, bool displayNames = false, QWidget *parent = nullptr); JoySensor *getSensor() const; bool ifDisplayNames() const; signals: void buttonSlotChanged(); public slots: void toggleNameDisplay(); private slots: void propagateSlotsChanged(); void openSensorButtonDialog(JoySensorButtonPushButton *pushbutton); void showSensorDialog(); private: JoySensor *m_sensor; bool m_display_names; bool m_keypad_unlocked; JoySensorButtonPushButton *m_up_button; JoySensorButtonPushButton *m_down_button; JoySensorButtonPushButton *m_left_button; JoySensorButtonPushButton *m_right_button; JoySensorButtonPushButton *m_fwd_button; JoySensorButtonPushButton *m_bwd_button; JoySensorPushButton *m_sensor_widget; JoySensorButtonPushButton *generateBtnToGrid(JoySensorDirection sensorDir, int gridRow, int gridCol); }; AntiMicroX-antimicrox-b300273/src/setjoystick.cpp000066400000000000000000001045351471077622000220300ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "setjoystick.h" #include "globalvariables.h" #include "inputdevice.h" #include "joybuttontypes/joybutton.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joybuttontypes/joysensorbutton.h" #include "joycontrolstick.h" #include "joydpad.h" #include "joysensor.h" #include "joysensorfactory.h" #include "vdpad.h" #include #include #include SetJoystick::SetJoystick(InputDevice *device, int index, QObject *parent) : SetJoystickXml(this, parent) { m_device = device; m_index = index; reset(); } SetJoystick::SetJoystick(InputDevice *device, int index, bool runreset, QObject *parent) : SetJoystickXml(this, parent) { m_device = device; m_index = index; if (runreset) reset(); } SetJoystick::~SetJoystick() { removeAllBtnFromQueue(); } JoyButton *SetJoystick::getJoyButton(int index) const { return getButtons().value(index); } JoyAxis *SetJoystick::getJoyAxis(int index) const { Q_ASSERT(!axes.isEmpty()); return axes.value(index); } JoyDPad *SetJoystick::getJoyDPad(int index) const { return getHats().value(index); } VDPad *SetJoystick::getVDPad(int index) const { return getVdpads().value(index); } JoyControlStick *SetJoystick::getJoyStick(int index) const { return getSticks().value(index); } JoySensor *SetJoystick::getSensor(JoySensorType type) const { return m_sensors.value(type); } void SetJoystick::refreshButtons() { deleteButtons(); for (int i = 0; i < m_device->getNumberRawButtons(); i++) { JoyButton *button = new JoyButton(i, m_index, this, this); m_buttons.insert(i, button); enableButtonConnections(button); } } void SetJoystick::refreshAxes() { deleteAxes(); InputDevice *device = getInputDevice(); for (int i = 0; i < device->getNumberRawAxes(); i++) { JoyAxis *axis = new JoyAxis(i, m_index, this, this); axes.insert(i, axis); if (device->hasCalibrationThrottle(i)) { JoyAxis::ThrottleTypes throttle = device->getCalibrationThrottle(i); axis->setInitialThrottle(throttle); } enableAxisConnections(axis); } } void SetJoystick::refreshHats() { deleteHats(); for (int i = 0; i < m_device->getNumberRawHats(); i++) { JoyDPad *dpad = new JoyDPad(i, m_index, this, this); hats.insert(i, dpad); enableHatConnections(dpad); } } /** * @brief Setup sensor objects for all available hardware sensors. */ void SetJoystick::refreshSensors() { deleteSensors(); for (size_t i = 0; i < SENSOR_COUNT; ++i) { JoySensorType type = static_cast(i); if (!getInputDevice()->hasRawSensor(type)) continue; JoySensor *sensor = JoySensorFactory::build(type, getInputDevice()->getRawSensorRate(type), m_index, this, this); m_sensors.insert(type, sensor); enableSensorConnections(sensor); } } void SetJoystick::deleteButtons() { QHashIterator iter(getButtons()); while (iter.hasNext()) { JoyButton *button = iter.next().value(); if (button != nullptr) { button->deleteLater(); button = nullptr; } } m_buttons.clear(); } void SetJoystick::deleteAxes() { QHashIterator iter(axes); while (iter.hasNext()) { JoyAxis *axis = iter.next().value(); if (axis != nullptr) { axes.remove(iter.key()); axis->deleteLater(); } } axes.clear(); } void SetJoystick::deleteSticks() { QHashIterator iter(getSticks()); while (iter.hasNext()) { JoyControlStick *stick = iter.next().value(); if (stick != nullptr) { stick->deleteLater(); stick = nullptr; } } sticks.clear(); } void SetJoystick::deleteVDpads() { QHashIterator iter(getVdpads()); while (iter.hasNext()) { VDPad *dpad = iter.next().value(); if (dpad != nullptr) { dpad->deleteLater(); dpad = nullptr; } } vdpads.clear(); } void SetJoystick::deleteHats() { QHashIterator iter(getHats()); while (iter.hasNext()) { JoyDPad *dpad = iter.next().value(); if (dpad != nullptr) { hats.remove(iter.key()); dpad->deleteLater(); } } hats.clear(); } /** * @brief Destroy all sensor objects in this set */ void SetJoystick::deleteSensors() { for (const auto &sensor : m_sensors) { if (sensor != nullptr) sensor->deleteLater(); } m_sensors.clear(); } int SetJoystick::getNumberButtons() const { return getButtons().count(); } int SetJoystick::getNumberAxes() const { return axes.count(); } int SetJoystick::getNumberHats() const { return getHats().count(); } int SetJoystick::getNumberSticks() const { return getSticks().size(); } /** * @brief Checks if this set has a sensor * @returns True if sensor type is present, false otherwise. */ bool SetJoystick::hasSensor(JoySensorType type) const { return m_sensors.contains(type); } int SetJoystick::getNumberVDPads() const { return getVdpads().size(); } /** * @brief Re-enumerates inputs from the associated device and * resets all mappings in this set. */ void SetJoystick::reset() { deleteSticks(); deleteSensors(); deleteVDpads(); refreshAxes(); refreshSensors(); refreshButtons(); refreshHats(); m_name = QString(); } void SetJoystick::propogateSetChange(int index) { emit setChangeActivated(index); } void SetJoystick::propogateSetButtonAssociation(int button, int newset, int mode) { if (newset != m_index) emit setAssignmentButtonChanged(button, m_index, newset, mode); } void SetJoystick::propogateSetAxisButtonAssociation(int button, int axis, int newset, int mode) { if (newset != m_index) emit setAssignmentAxisChanged(button, axis, m_index, newset, mode); } void SetJoystick::propogateSetStickButtonAssociation(int button, int stick, int newset, int mode) { if (newset != m_index) emit setAssignmentStickChanged(button, stick, m_index, newset, mode); } /** * @brief Forwards set change slot mapping event to InputDevice */ void SetJoystick::propagateSetSensorButtonAssociation(JoySensorDirection direction, JoySensorType sensor, int newset, int mode) { if (newset != m_index) emit setAssignmentSensorChanged(direction, sensor, m_index, newset, mode); } void SetJoystick::propogateSetDPadButtonAssociation(int button, int dpad, int newset, int mode) { if (newset != m_index) emit setAssignmentDPadChanged(button, dpad, m_index, newset, mode); } void SetJoystick::propogateSetVDPadButtonAssociation(int button, int dpad, int newset, int mode) { if (newset != m_index) emit setAssignmentVDPadChanged(button, dpad, m_index, newset, mode); } /** * @brief Perform a release of all elements of a set. Stick and vdpad * releases will be handled by the associated button or axis. */ void SetJoystick::release() { QHashIterator iterAxes(axes); while (iterAxes.hasNext()) { JoyAxis *axis = iterAxes.next().value(); axis->clearPendingEvent(); axis->joyEvent(axis->getCurrentThrottledDeadValue(), true); axis->eventReset(); } QHashIterator iterDPads(getHats()); while (iterDPads.hasNext()) { JoyDPad *dpad = iterDPads.next().value(); dpad->clearPendingEvent(); dpad->joyEvent(0, true); dpad->eventReset(); } for (auto &sensor : m_sensors) { float values[3] = {0}; sensor->clearPendingEvent(); sensor->joyEvent(values, true); } QHashIterator iterButtons(getButtons()); while (iterButtons.hasNext()) { JoyButton *button = iterButtons.next().value(); button->clearPendingEvent(); button->joyEvent(false, true); button->eventReset(); } } /** * @brief Check if this set has any mapped event. * @returns True if any event is mapped to a keyboard or mouse event, false otherwise. */ bool SetJoystick::isSetEmpty() { bool result = true; QHashIterator iter(getButtons()); while (iter.hasNext() && result) { JoyButton *button = iter.next().value(); if (!button->isDefault()) result = false; } QHashIterator iter2(axes); while (iter2.hasNext() && result) { JoyAxis *axis = iter2.next().value(); if (!axis->isDefault()) result = false; } QHashIterator iter3(getHats()); while (iter3.hasNext() && result) { JoyDPad *dpad = iter3.next().value(); if (!dpad->isDefault()) result = false; } QHashIterator iter4(getSticks()); while (iter4.hasNext() && result) { JoyControlStick *stick = iter4.next().value(); if (!stick->isDefault()) result = false; } for (const auto &sensor : m_sensors) { if (!result) break; if (!sensor->isDefault()) result = false; } QHashIterator iter5(getVdpads()); while (iter5.hasNext() && result) { VDPad *vdpad = iter5.next().value(); if (!vdpad->isDefault()) result = false; } return result; } void SetJoystick::propogateSetAxisThrottleSetting(int index) { JoyAxis *axis = axes.value(index); if (axis != nullptr) emit setAssignmentAxisThrottleChanged(index, axis->getCurrentlyAssignedSet()); } void SetJoystick::addControlStick(int index, JoyControlStick *stick) { sticks.insert(index, stick); connect(stick, &JoyControlStick::stickNameChanged, this, &SetJoystick::propogateSetStickNameChange); QHashIterator iter(*stick->getButtons()); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button != nullptr) { connect(button, &JoyControlStickButton::setChangeActivated, this, &SetJoystick::propogateSetChange); connect(button, &JoyControlStickButton::setAssignmentChanged, this, &SetJoystick::propogateSetStickButtonAssociation); connect(button, &JoyControlStickButton::clicked, this, &SetJoystick::propogateSetStickButtonClick, Qt::QueuedConnection); connect(button, &JoyControlStickButton::released, this, &SetJoystick::propogateSetStickButtonRelease, Qt::QueuedConnection); connect(button, &JoyControlStickButton::buttonNameChanged, this, &SetJoystick::propogateSetStickButtonNameChange); } } } void SetJoystick::removeControlStick(int index) { if (sticks.contains(index)) { JoyControlStick *stick = getSticks().value(index); sticks.remove(index); stick->deleteLater(); stick = nullptr; } } void SetJoystick::addVDPad(int index, VDPad *vdpad) { vdpads.insert(index, vdpad); connect(vdpad, &VDPad::dpadNameChanged, this, &SetJoystick::propogateSetVDPadNameChange); QHashIterator iter(*vdpad->getButtons()); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); if (button != nullptr) { connect(button, &JoyDPadButton::setChangeActivated, this, &SetJoystick::propogateSetChange); connect(button, &JoyDPadButton::setAssignmentChanged, this, &SetJoystick::propogateSetVDPadButtonAssociation); connect(button, &JoyDPadButton::clicked, this, &SetJoystick::propogateSetDPadButtonClick, Qt::QueuedConnection); connect(button, &JoyDPadButton::released, this, &SetJoystick::propogateSetDPadButtonRelease, Qt::QueuedConnection); connect(button, &JoyDPadButton::buttonNameChanged, this, &SetJoystick::propogateSetVDPadButtonNameChange); } } } void SetJoystick::removeVDPad(int index) { if (vdpads.contains(index)) { VDPad *vdpad = vdpads.value(index); vdpads.remove(index); vdpad->deleteLater(); vdpad = nullptr; } } int SetJoystick::getIndex() const { return m_index; } int SetJoystick::getRealIndex() const { return m_index + 1; } void SetJoystick::propogateSetButtonClick(int button) { JoyButton *jButton = qobject_cast(sender()); if (jButton != nullptr && !jButton->getIgnoreEventState()) { emit setButtonClick(m_index, button); lastClickedButtons.append(jButton); qDebug() << "Added button " << jButton->getPartialName(false, true) << " to list"; qDebug() << "List has " << getLastClickedButtons().count() << " buttons"; } } QList const &SetJoystick::getLastClickedButtons() const { return lastClickedButtons; } void SetJoystick::removeAllBtnFromQueue() { if (!getLastClickedButtons().isEmpty()) lastClickedButtons.clear(); } int SetJoystick::getCountBtnInList(QString partialName) { int count = 0; foreach (const JoyButton *joyBtn, getLastClickedButtons()) { if (joyBtn->getPartialName(false, true) == partialName) count++; } return count; } void SetJoystick::propogateSetButtonRelease(int button) { JoyButton *jButton = qobject_cast(sender()); if (jButton != nullptr) { if (!jButton->getIgnoreEventState()) emit setButtonRelease(m_index, button); } } void SetJoystick::propogateSetAxisButtonClick(int button) { JoyAxisButton *axisButton = qobject_cast(sender()); if (axisButton != nullptr) { JoyAxis *axis = axisButton->getAxis(); if (!axisButton->getIgnoreEventState()) emit setAxisButtonClick(m_index, axis->getIndex(), button); } } void SetJoystick::propogateSetAxisButtonRelease(int button) { JoyAxisButton *axisButton = qobject_cast(sender()); if (axisButton != nullptr) { JoyAxis *axis = axisButton->getAxis(); if (!axisButton->getIgnoreEventState()) emit setAxisButtonRelease(m_index, axis->getIndex(), button); } } void SetJoystick::propogateSetStickButtonClick(int button) { JoyControlStickButton *stickButton = qobject_cast(sender()); if (stickButton != nullptr) { JoyControlStick *stick = stickButton->getStick(); if (stick && !stickButton->getIgnoreEventState()) emit setStickButtonClick(m_index, stick->getIndex(), button); } } void SetJoystick::propogateSetStickButtonRelease(int button) { JoyControlStickButton *stickButton = qobject_cast(sender()); if (stickButton != nullptr) { JoyControlStick *stick = stickButton->getStick(); if (!stickButton->getIgnoreEventState()) emit setStickButtonRelease(m_index, stick->getIndex(), button); } } void SetJoystick::propagateSetSensorButtonClick(int button) { JoySensorButton *sensorButton = qobject_cast(sender()); if (sensorButton != nullptr) { JoySensor *sensor = sensorButton->getSensor(); if (sensor && !sensorButton->getIgnoreEventState()) emit setSensorButtonClick(m_index, sensor->getType(), static_cast(button)); } } void SetJoystick::propagateSetSensorButtonRelease(int button) { JoySensorButton *sensorButton = qobject_cast(sender()); if (sensorButton != nullptr) { JoySensor *sensor = sensorButton->getSensor(); if (!sensorButton->getIgnoreEventState()) emit setSensorButtonRelease(m_index, sensor->getType(), static_cast(button)); } } void SetJoystick::propogateSetDPadButtonClick(int button) { JoyDPadButton *dpadButton = qobject_cast(sender()); if (dpadButton) { JoyDPad *dpad = dpadButton->getDPad(); if (dpad && dpadButton->getButtonState() && !dpadButton->getIgnoreEventState()) { emit setDPadButtonClick(m_index, dpad->getIndex(), button); } } } void SetJoystick::propogateSetDPadButtonRelease(int button) { JoyDPadButton *dpadButton = qobject_cast(sender()); if (dpadButton != nullptr) { JoyDPad *dpad = dpadButton->getDPad(); if (dpad && !dpadButton->getButtonState() && !dpadButton->getIgnoreEventState()) { emit setDPadButtonRelease(m_index, dpad->getIndex(), button); } } } void SetJoystick::propogateSetButtonNameChange() { JoyButton *button = qobject_cast(sender()); disconnect(button, &JoyButton::buttonNameChanged, this, &SetJoystick::propogateSetButtonNameChange); emit setButtonNameChange(button->getJoyNumber()); connect(button, &JoyButton::buttonNameChanged, this, &SetJoystick::propogateSetButtonNameChange); } void SetJoystick::propogateSetAxisButtonNameChange() { JoyAxisButton *button = qobject_cast(sender()); disconnect(button, &JoyAxisButton::buttonNameChanged, this, &SetJoystick::propogateSetAxisButtonNameChange); emit setAxisButtonNameChange(button->getAxis()->getIndex(), button->getJoyNumber()); connect(button, &JoyAxisButton::buttonNameChanged, this, &SetJoystick::propogateSetAxisButtonNameChange); } void SetJoystick::propogateSetStickButtonNameChange() { JoyControlStickButton *button = qobject_cast(sender()); disconnect(button, &JoyControlStickButton::buttonNameChanged, this, &SetJoystick::propogateSetStickButtonNameChange); emit setStickButtonNameChange(button->getStick()->getIndex(), button->getJoyNumber()); connect(button, &JoyControlStickButton::buttonNameChanged, this, &SetJoystick::propogateSetStickButtonNameChange); } /** * @brief Propagate button rename event to InputDevice */ void SetJoystick::propagateSetSensorButtonNameChange() { JoySensorButton *button = qobject_cast(sender()); disconnect(button, &JoySensorButton::buttonNameChanged, this, &SetJoystick::propagateSetSensorButtonNameChange); emit setSensorButtonNameChange(button->getSensor()->getType(), static_cast(button->getJoyNumber())); connect(button, &JoySensorButton::buttonNameChanged, this, &SetJoystick::propagateSetSensorButtonNameChange); } void SetJoystick::propogateSetDPadButtonNameChange() { JoyDPadButton *button = qobject_cast(sender()); disconnect(button, &JoyDPadButton::buttonNameChanged, this, &SetJoystick::propogateSetDPadButtonNameChange); emit setDPadButtonNameChange(button->getDPad()->getIndex(), button->getJoyNumber()); connect(button, &JoyDPadButton::buttonNameChanged, this, &SetJoystick::propogateSetDPadButtonNameChange); } void SetJoystick::propogateSetVDPadButtonNameChange() { JoyDPadButton *button = qobject_cast(sender()); disconnect(button, &JoyDPadButton::buttonNameChanged, this, &SetJoystick::propogateSetVDPadButtonNameChange); emit setVDPadButtonNameChange(button->getDPad()->getIndex(), button->getJoyNumber()); connect(button, &JoyDPadButton::buttonNameChanged, this, &SetJoystick::propogateSetVDPadButtonNameChange); } void SetJoystick::propogateSetAxisNameChange() { JoyAxis *axis = qobject_cast(sender()); disconnect(axis, &JoyAxis::axisNameChanged, this, &SetJoystick::propogateSetAxisNameChange); emit setAxisNameChange(axis->getIndex()); connect(axis, &JoyAxis::axisNameChanged, this, &SetJoystick::propogateSetAxisNameChange); } void SetJoystick::propogateSetStickNameChange() { JoyControlStick *stick = qobject_cast(sender()); disconnect(stick, &JoyControlStick::stickNameChanged, this, &SetJoystick::propogateSetStickNameChange); emit setStickNameChange(stick->getIndex()); connect(stick, &JoyControlStick::stickNameChanged, this, &SetJoystick::propogateSetStickNameChange); } void SetJoystick::propagateSetSensorNameChange() { JoySensor *sensor = qobject_cast(sender()); disconnect(sensor, &JoySensor::sensorNameChanged, this, &SetJoystick::propagateSetSensorNameChange); emit setSensorNameChange(sensor->getType()); connect(sensor, &JoySensor::sensorNameChanged, this, &SetJoystick::propagateSetSensorNameChange); } void SetJoystick::propogateSetDPadNameChange() { JoyDPad *dpad = qobject_cast(sender()); disconnect(dpad, &JoyDPad::dpadNameChanged, this, &SetJoystick::propogateSetDPadButtonNameChange); emit setDPadNameChange(dpad->getIndex()); connect(dpad, &JoyDPad::dpadNameChanged, this, &SetJoystick::propogateSetDPadButtonNameChange); } void SetJoystick::propogateSetVDPadNameChange() { VDPad *vdpad = qobject_cast(sender()); disconnect(vdpad, &VDPad::dpadNameChanged, this, &SetJoystick::propogateSetVDPadNameChange); emit setVDPadNameChange(vdpad->getIndex()); connect(vdpad, &VDPad::dpadNameChanged, this, &SetJoystick::propogateSetVDPadNameChange); } void SetJoystick::setIgnoreEventState(bool ignore) { QHashIterator iter(getButtons()); while (iter.hasNext()) { JoyButton *button = iter.next().value(); if (button != nullptr) button->setIgnoreEventState(ignore); } QHashIterator iter2(axes); while (iter2.hasNext()) { JoyAxis *axis = iter2.next().value(); if (axis != nullptr) { JoyAxisButton *naxisbutton = axis->getNAxisButton(); naxisbutton->setIgnoreEventState(ignore); JoyAxisButton *paxisbutton = axis->getPAxisButton(); paxisbutton->setIgnoreEventState(ignore); } } QHashIterator iter3(getHats()); while (iter3.hasNext()) { JoyDPad *dpad = iter3.next().value(); if (dpad != nullptr) { QHash *dpadbuttons = dpad->getButtons(); QHashIterator iterdpadbuttons(*dpadbuttons); while (iterdpadbuttons.hasNext()) { JoyDPadButton *dpadbutton = iterdpadbuttons.next().value(); if (dpadbutton) dpadbutton->setIgnoreEventState(ignore); } } } QHashIterator iter4(getSticks()); while (iter4.hasNext()) { JoyControlStick *stick = iter4.next().value(); if (stick != nullptr) { QHash *stickButtons = stick->getButtons(); QHashIterator iterstickbuttons(*stickButtons); while (iterstickbuttons.hasNext()) { JoyControlStickButton *stickbutton = iterstickbuttons.next().value(); stickbutton->setIgnoreEventState(ignore); } } } QHashIterator iter5(getVdpads()); while (iter5.hasNext()) { VDPad *vdpad = iter5.next().value(); if (vdpad != nullptr) { QHash *dpadbuttons = vdpad->getButtons(); QHashIterator itervdpadbuttons(*dpadbuttons); while (itervdpadbuttons.hasNext()) { JoyDPadButton *dpadbutton = itervdpadbuttons.next().value(); dpadbutton->setIgnoreEventState(ignore); } } } } void SetJoystick::propogateSetAxisActivated(int value) { JoyAxis *axis = qobject_cast(sender()); // static_cast emit setAxisActivated(m_index, axis->getIndex(), value); } void SetJoystick::propogateSetAxisReleased(int value) { JoyAxis *axis = qobject_cast(sender()); // static_cast emit setAxisReleased(m_index, axis->getIndex(), value); } void SetJoystick::enableButtonConnections(JoyButton *button) { connect(button, &JoyButton::setChangeActivated, this, &SetJoystick::propogateSetChange); connect(button, &JoyButton::setAssignmentChanged, this, &SetJoystick::propogateSetButtonAssociation); connect(button, &JoyButton::clicked, this, &SetJoystick::propogateSetButtonClick, Qt::QueuedConnection); connect(button, &JoyButton::clicked, m_device, &InputDevice::buttonClickEvent, Qt::QueuedConnection); connect(button, &JoyButton::released, this, &SetJoystick::propogateSetButtonRelease); connect(button, &JoyButton::released, m_device, &InputDevice::buttonReleaseEvent); connect(button, &JoyButton::buttonNameChanged, this, &SetJoystick::propogateSetButtonNameChange); } void SetJoystick::enableAxisConnections(JoyAxis *axis) { connect(axis, &JoyAxis::throttleChangePropogated, this, &SetJoystick::propogateSetAxisThrottleSetting); connect(axis, &JoyAxis::axisNameChanged, this, &SetJoystick::propogateSetAxisNameChange); connect(axis, &JoyAxis::active, this, &SetJoystick::propogateSetAxisActivated); connect(axis, &JoyAxis::released, this, &SetJoystick::propogateSetAxisReleased); JoyAxisButton *button = axis->getNAxisButton(); connect(button, &JoyAxisButton::setChangeActivated, this, &SetJoystick::propogateSetChange); connect(button, &JoyAxisButton::setAssignmentChanged, this, &SetJoystick::propogateSetAxisButtonAssociation); connect(button, &JoyAxisButton::clicked, this, &SetJoystick::propogateSetAxisButtonClick, Qt::QueuedConnection); connect(button, &JoyAxisButton::released, this, &SetJoystick::propogateSetAxisButtonRelease, Qt::QueuedConnection); connect(button, &JoyAxisButton::buttonNameChanged, this, &SetJoystick::propogateSetAxisButtonNameChange); button = axis->getPAxisButton(); connect(button, &JoyAxisButton::setChangeActivated, this, &SetJoystick::propogateSetChange); connect(button, &JoyAxisButton::setAssignmentChanged, this, &SetJoystick::propogateSetAxisButtonAssociation); connect(button, &JoyAxisButton::clicked, this, &SetJoystick::propogateSetAxisButtonClick, Qt::QueuedConnection); connect(button, &JoyAxisButton::released, this, &SetJoystick::propogateSetAxisButtonRelease, Qt::QueuedConnection); connect(button, &JoyAxisButton::buttonNameChanged, this, &SetJoystick::propogateSetAxisButtonNameChange); } void SetJoystick::enableHatConnections(JoyDPad *dpad) { connect(dpad, &JoyDPad::dpadNameChanged, this, &SetJoystick::propogateSetDPadNameChange); QHash *buttons = dpad->getJoyButtons(); QHashIterator iter(*buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); connect(button, &JoyDPadButton::setChangeActivated, this, &SetJoystick::propogateSetChange); connect(button, &JoyDPadButton::setAssignmentChanged, this, &SetJoystick::propogateSetDPadButtonAssociation); connect(button, &JoyDPadButton::clicked, this, &SetJoystick::propogateSetDPadButtonClick, Qt::QueuedConnection); connect(button, &JoyDPadButton::clicked, m_device, &InputDevice::dpadButtonClickEvent, Qt::QueuedConnection); connect(button, &JoyDPadButton::released, this, &SetJoystick::propogateSetDPadButtonRelease, Qt::QueuedConnection); connect(button, &JoyDPadButton::released, m_device, &InputDevice::dpadButtonReleaseEvent, Qt::QueuedConnection); connect(button, &JoyDPadButton::buttonNameChanged, this, &SetJoystick::propogateSetDPadButtonNameChange); } } /** * @brief Establishes connections for event propagation between JoySensor and InputDevice */ void SetJoystick::enableSensorConnections(JoySensor *sensor) { connect(sensor, &JoySensor::sensorNameChanged, this, &SetJoystick::propagateSetSensorNameChange); auto buttons = sensor->getButtons(); for (auto iter = buttons->cbegin(); iter != buttons->cend(); ++iter) { connect(iter.value(), &JoySensorButton::setChangeActivated, this, &SetJoystick::propogateSetChange); connect(iter.value(), &JoySensorButton::setAssignmentChanged, this, &SetJoystick::propagateSetSensorButtonAssociation); connect(iter.value(), &JoySensorButton::clicked, this, &SetJoystick::propagateSetSensorButtonClick, Qt::QueuedConnection); connect(iter.value(), &JoySensorButton::released, this, &SetJoystick::propagateSetSensorButtonRelease, Qt::QueuedConnection); connect(iter.value(), &JoySensorButton::buttonNameChanged, this, &SetJoystick::propagateSetSensorButtonNameChange); } } InputDevice *SetJoystick::getInputDevice() const { return m_device; } void SetJoystick::setName(QString name) { if (name.length() <= GlobalVariables::SetJoystick::MAXNAMELENGTH) { m_name = name; emit propertyUpdated(); } else { name.truncate(GlobalVariables::SetJoystick::MAXNAMELENGTH - 3); // Truncate name to 27 characters. Add ellipsis at the end. m_name = QString(name).append("..."); emit propertyUpdated(); } } QString SetJoystick::getName() const { return m_name; } void SetJoystick::copyAssignments(SetJoystick *destSet) { for (int i = 0; i < m_device->getNumberAxes(); i++) { JoyAxis *sourceAxis = axes.value(i); JoyAxis *destAxis = destSet->axes.value(i); if (sourceAxis && destAxis) sourceAxis->copyAssignments(destAxis); } QHashIterator stickIter(getSticks()); while (stickIter.hasNext()) { stickIter.next(); int index = stickIter.key(); JoyControlStick *sourceStick = stickIter.value(); JoyControlStick *destStick = destSet->getSticks().value(index); if (sourceStick && destStick) sourceStick->copyAssignments(destStick); } for (auto iter = m_sensors.cbegin(); iter != m_sensors.cend(); ++iter) { JoySensorType type = iter.key(); JoySensor *sourceSensor = iter.value(); JoySensor *destSensor = destSet->getSensor(type); if (sourceSensor && destSensor) sourceSensor->copyAssignments(destSensor); } for (int i = 0; i < m_device->getNumberHats(); i++) { JoyDPad *sourceDPad = getHats().value(i); JoyDPad *destDPad = destSet->getHats().value(i); if (sourceDPad && destDPad) sourceDPad->copyAssignments(destDPad); } QHashIterator vdpadIter(getVdpads()); while (vdpadIter.hasNext()) { vdpadIter.next(); int index = vdpadIter.key(); VDPad *sourceVDpad = vdpadIter.value(); VDPad *destVDPad = destSet->getVdpads().value(index); if (sourceVDpad && destVDPad) sourceVDpad->copyAssignments(destVDPad); } for (int i = 0; i < m_device->getNumberButtons(); i++) { JoyButton *sourceButton = getButtons().value(i); JoyButton *destButton = destSet->getButtons().value(i); if (sourceButton && destButton) sourceButton->copyAssignments(destButton); } } QString SetJoystick::getSetLabel() { QString temp = QString(); if (!m_name.isEmpty()) temp = tr("Set %1: %2").arg(m_index + 1).arg(m_name); else temp = tr("Set %1").arg(m_index + 1); return temp; } void SetJoystick::establishPropertyUpdatedConnection() { connect(this, &SetJoystick::propertyUpdated, getInputDevice(), &InputDevice::profileEdited); } void SetJoystick::disconnectPropertyUpdatedConnection() { disconnect(this, &SetJoystick::propertyUpdated, getInputDevice(), &InputDevice::profileEdited); } /** * @brief Raise the dead zones for axes. Used when launching * the controller mapping window. */ void SetJoystick::raiseAxesDeadZones(int deadZone) { int tempDeadZone = deadZone; if ((deadZone <= 0) || (deadZone > 32767)) tempDeadZone = GlobalVariables::SetJoystick::RAISEDDEADZONE; QHashIterator axisIter(axes); while (axisIter.hasNext()) { JoyAxis *temp = axisIter.next().value(); temp->disconnectPropertyUpdatedConnection(); temp->setDeadZone(tempDeadZone); temp->establishPropertyUpdatedConnection(); } } void SetJoystick::currentAxesDeadZones(QList *axesDeadZones) { QHashIterator axisIter(axes); while (axisIter.hasNext()) { JoyAxis *temp = axisIter.next().value(); axesDeadZones->append(temp->getDeadZone()); } } void SetJoystick::setAxesDeadZones(QList *axesDeadZones) { QListIterator iter(*axesDeadZones); int axisNum = 0; while (iter.hasNext()) { int deadZoneValue = iter.next(); if (axes.contains(axisNum)) { JoyAxis *temp = getJoyAxis(axisNum); temp->disconnectPropertyUpdatedConnection(); temp->setDeadZone(deadZoneValue); temp->establishPropertyUpdatedConnection(); } axisNum++; } } void SetJoystick::setAxisThrottle(int axisNum, JoyAxis::ThrottleTypes throttle) { if (axes.contains(axisNum)) { JoyAxis *temp = axes.value(axisNum); temp->setInitialThrottle(throttle); } } QHash *SetJoystick::getAxes() { return &axes; } QHash const &SetJoystick::getButtons() const { return m_buttons; } QHash const &SetJoystick::getHats() const { return hats; } QHash const &SetJoystick::getSticks() const { return sticks; } /** * @brief Get all sensor objects in this set. * @returns Sensors in this set */ QHash const &SetJoystick::getSensors() const { return m_sensors; } QHash const &SetJoystick::getVdpads() const { return vdpads; } AntiMicroX-antimicrox-b300273/src/setjoystick.h000066400000000000000000000235241471077622000214730ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SETJOYSTICK_H #define SETJOYSTICK_H #include "joyaxis.h" #include "joysensordirection.h" #include "joysensortype.h" #include "xml/setjoystickxml.h" class InputDevice; class JoyButton; class JoyDPad; class JoyControlStick; class JoySensor; class VDPad; /** * @brief A set of mapped events which can by switched by a controller event. * Contains controller input objects like axes or buttons and their mappings, * and forwards some QT GUI events. */ class SetJoystick : public SetJoystickXml { Q_OBJECT public: explicit SetJoystick(InputDevice *device, int index, QObject *parent); explicit SetJoystick(InputDevice *device, int index, bool runreset, QObject *parent); ~SetJoystick(); JoyAxis *getJoyAxis(int index) const; JoyButton *getJoyButton(int index) const; JoyDPad *getJoyDPad(int index) const; JoyControlStick *getJoyStick(int index) const; JoySensor *getSensor(JoySensorType type) const; VDPad *getVDPad(int index) const; int getNumberButtons() const; int getNumberAxes() const; int getNumberHats() const; int getNumberSticks() const; bool hasSensor(JoySensorType type) const; int getNumberVDPads() const; QHash const &getButtons() const; QHash const &getHats() const; QHash const &getSticks() const; QHash const &getSensors() const; QHash const &getVdpads() const; QHash *getAxes(); int getIndex() const; int getRealIndex() const; virtual void refreshButtons(); // SetButton class virtual void refreshAxes(); // SetAxis class virtual void refreshHats(); // SetHat class virtual void refreshSensors(); void release(); void addControlStick(int index, JoyControlStick *stick); // SetStick class void removeControlStick(int index); // SetStick class void addVDPad(int index, VDPad *vdpad); // SetVDPad class void removeVDPad(int index); // SetVDPad class void setIgnoreEventState(bool ignore); InputDevice *getInputDevice() const; void setName(QString name); QString getName() const; QString getSetLabel(); void raiseAxesDeadZones(int deadZone = 0); // SetAxis class void currentAxesDeadZones(QList *axesDeadZones); // SetAxis class void setAxesDeadZones(QList *axesDeadZones); // SetAxis class void setAxisThrottle(int axisNum, JoyAxis::ThrottleTypes throttle); // SetAxis class QList const &getLastClickedButtons() const; void removeAllBtnFromQueue(); int getCountBtnInList(QString partialName); bool isSetEmpty(); protected: void deleteButtons(); // SetButton class void deleteAxes(); // SetAxis class void deleteHats(); // SetHat class void deleteSticks(); // SetStick class void deleteSensors(); void deleteVDpads(); // SetVDPad class void enableButtonConnections(JoyButton *button); // SetButton class void enableAxisConnections(JoyAxis *axis); // SetAxis class void enableHatConnections(JoyDPad *dpad); // SetHat class void enableSensorConnections(JoySensor *sensor); signals: void setChangeActivated(int index); void setAssignmentButtonChanged(int button, int originset, int newset, int mode); // SetButton class void setAssignmentAxisChanged(int button, int axis, int originset, int newset, int mode); // SetAxis class void setAssignmentStickChanged(int button, int stick, int originset, int newset, int mode); // SetStick class void setAssignmentSensorChanged(JoySensorDirection direction, JoySensorType sensor, int originset, int newset, int mode); void setAssignmentDPadChanged(int button, int dpad, int originset, int newset, int mode); // SetHat class void setAssignmentVDPadChanged(int button, int dpad, int originset, int newset, int mode); // SetVDPad class void setAssignmentAxisThrottleChanged(int axis, int originset); // SetAxis class void setButtonClick(int index, int button); // SetButton class void setButtonRelease(int index, int button); // SetButton class void setAxisButtonClick(int setindex, int axis, int button); // SetAxis class void setAxisButtonRelease(int setindex, int axis, int button); // SetAxis class void setAxisActivated(int setindex, int axis, int value); // SetAxis class void setAxisReleased(int setindex, int axis, int value); // SetAxis class void setStickButtonClick(int setindex, int stick, int button); // SetStick class void setStickButtonRelease(int setindex, int stick, int button); // SetStick class void setSensorActivated(int setindex, JoySensorType type, int value); void setSensorReleased(int setindex, JoySensorType, int value); void setSensorButtonClick(int setindex, JoySensorType type, JoySensorDirection direction); void setSensorButtonRelease(int setindex, JoySensorType type, JoySensorDirection direction); void setDPadButtonClick(int setindex, int dpad, int button); // SetHat class void setDPadButtonRelease(int setindex, int dpad, int button); // SetHat class void setButtonNameChange(int index); // SetButton class void setAxisButtonNameChange(int axisIndex, int buttonIndex); // SetAxis class void setStickButtonNameChange(int stickIndex, int buttonIndex); // SetStick class void setSensorButtonNameChange(JoySensorType type, JoySensorDirection direction); void setDPadButtonNameChange(int dpadIndex, int buttonIndex); // SetHat class void setVDPadButtonNameChange(int vdpadIndex, int buttonIndex); // SetVDPad class void setAxisNameChange(int axisIndex); // SetAxis class void setStickNameChange(int stickIndex); // SetStick class void setSensorNameChange(JoySensorType type); void setDPadNameChange(int dpadIndex); // SetHat class void setVDPadNameChange(int vdpadIndex); // SetVDPad class void propertyUpdated(); public slots: virtual void reset(); void copyAssignments(SetJoystick *destSet); void propogateSetChange(int index); void propogateSetButtonAssociation(int button, int newset, int mode); // SetButton class void propogateSetAxisButtonAssociation(int button, int axis, int newset, int mode); // SetAxis class void propogateSetStickButtonAssociation(int button, int stick, int newset, int mode); // SetStick class void propagateSetSensorButtonAssociation(JoySensorDirection direction, JoySensorType sensor, int newset, int mode); void propogateSetDPadButtonAssociation(int button, int dpad, int newset, int mode); // SetHat class void propogateSetVDPadButtonAssociation(int button, int dpad, int newset, int mode); // SetVDPad class void establishPropertyUpdatedConnection(); void disconnectPropertyUpdatedConnection(); protected slots: void propogateSetAxisThrottleSetting(int index); // SetAxis class void propogateSetButtonClick(int button); // SetButton class void propogateSetButtonRelease(int button); // SetButton class void propogateSetAxisButtonClick(int button); // SetAxis class void propogateSetAxisButtonRelease(int button); // SetAxis class void propogateSetStickButtonClick(int button); // SetStick class void propogateSetStickButtonRelease(int button); // SetStick class void propagateSetSensorButtonClick(int button); void propagateSetSensorButtonRelease(int button); void propogateSetDPadButtonClick(int button); // SetHat class void propogateSetDPadButtonRelease(int button); // SetHat class void propogateSetAxisActivated(int value); // SetAxis class void propogateSetAxisReleased(int value); // SetAxis class void propogateSetButtonNameChange(); // SetButton class void propogateSetAxisButtonNameChange(); // SetAxis class void propogateSetStickButtonNameChange(); // SetStick class void propagateSetSensorButtonNameChange(); void propogateSetDPadButtonNameChange(); // SetHat class void propogateSetVDPadButtonNameChange(); // SetVDPad class void propogateSetAxisNameChange(); // SetAxis class void propogateSetStickNameChange(); // SetStick class void propagateSetSensorNameChange(); void propogateSetDPadNameChange(); // SetHat class void propogateSetVDPadNameChange(); // SetVDPad class private: QHash m_buttons; QHash axes; QHash hats; QHash sticks; QHash m_sensors; QHash vdpads; QList lastClickedButtons; int m_index; InputDevice *m_device; QString m_name; }; Q_DECLARE_METATYPE(SetJoystick *) #endif // SETJOYSTICK_H AntiMicroX-antimicrox-b300273/src/simplekeygrabberbutton.cpp000066400000000000000000000231561471077622000242370ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "simplekeygrabberbutton.h" #include #include #include #include "antkeymapper.h" #include "event.h" #include "eventhandlerfactory.h" #include #include #include #include #ifdef Q_OS_WIN #include "winextras.h" #endif SimpleKeyGrabberButton::SimpleKeyGrabberButton(QWidget *parent) : QPushButton(parent) { grabNextAction = false; grabbingWheel = false; edited = false; this->installEventFilter(this); } void SimpleKeyGrabberButton::keyPressEvent(QKeyEvent *event) { // Do not allow closing of dialog using Escape key if (event->key() == Qt::Key_Escape) return; QPushButton::keyPressEvent(event); } bool SimpleKeyGrabberButton::eventFilter(QObject *obj, QEvent *event) { Q_UNUSED(obj); int controlcode = 0; if (grabNextAction && (event->type() == QEvent::MouseButtonRelease)) { QMouseEvent *mouseEve = static_cast(event); if (mouseEve->button() == Qt::RightButton) controlcode = 3; else if (mouseEve->button() == Qt::MiddleButton) controlcode = 2; else controlcode = mouseEve->button(); buttonslot.setSlotCode(controlcode); buttonslot.setSlotMode(JoyButtonSlot::JoyMouseButton); refreshButtonLabel(); edited = true; releaseMouse(); releaseKeyboard(); grabNextAction = grabbingWheel = false; emit buttonCodeChanged(controlcode); } else if (grabNextAction && (event->type() == static_cast(7))) { QKeyEvent *keyEve = static_cast(event); int tempcode = keyEve->nativeScanCode(); int virtualactual = keyEve->nativeVirtualKey(); BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); int finalvirtual = 0; int checkalias = 0; #ifdef Q_OS_WIN BACKEND_ELSE_IF(handler->getIdentifier() == "sendinput") { // Find more specific virtual key (VK_SHIFT -> VK_LSHIFT) // by checking for extended bit in scan code. finalvirtual = WinExtras::correctVirtualKey(tempcode, virtualactual); checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual, tempcode); } #elif defined(WITH_X11) finalvirtual = X11KeyCodeToX11KeySym(tempcode); // Obtain group 1 X11 keysym. Removes effects from modifiers. #ifdef WITH_UINPUT if (handler->getIdentifier() == "uinput") { QtKeyMapperBase *x11KeyMapper = AntKeyMapper::getInstance()->getNativeKeyMapper(); // Find Qt Key corresponding to X11 KeySym. checkalias = x11KeyMapper->returnQtKey(finalvirtual); finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey( checkalias); // Find corresponding Linux input key for the Qt key. } else #endif #ifdef WITH_XTEST if (handler->getIdentifier() == "xtest") checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); // Check for alias against group 1 keysym. else #endif { // Not using any known handler. finalvirtual = tempcode; checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); } #else if (QApplication::platformName() == QStringLiteral("xcb")) { finalvirtual = AntKeyMapper::getInstance()->returnVirtualKey(keyEve->key()); checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); } else { // Not running on xcb platform. finalvirtual = tempcode; checkalias = AntKeyMapper::getInstance()->returnQtKey(finalvirtual); } #endif controlcode = tempcode; bool valueUpdated = false; qDebug() << "slot string for simple key grab button is: " << buttonslot.getSlotString(); if ((keyEve->modifiers() & Qt::ControlModifier) && (keyEve->key() == Qt::Key_X)) { controlcode = 0; refreshButtonLabel(); } else if (controlcode <= 0) { controlcode = 0; setText(""); valueUpdated = true; edited = true; } else if ((checkalias > 0) && (finalvirtual > 0)) { buttonslot.setSlotCode(finalvirtual, checkalias); buttonslot.setSlotMode(JoyButtonSlot::JoyKeyboard); setText(keysymToKeyString(finalvirtual, checkalias).toUpper()); edited = true; valueUpdated = true; } else if (virtualactual > 0) { buttonslot.setSlotCode(virtualactual); buttonslot.setSlotMode(JoyButtonSlot::JoyKeyboard); setText(keysymToKeyString(virtualactual).toUpper()); edited = true; valueUpdated = true; } grabNextAction = false; grabbingWheel = false; releaseMouse(); releaseKeyboard(); if (valueUpdated) emit buttonCodeChanged(controlcode); } else if (grabNextAction && (event->type() == QEvent::Wheel) && !grabbingWheel) { grabbingWheel = true; } else if (grabNextAction && (event->type() == QEvent::Wheel)) { QWheelEvent *wheelEve = static_cast(event); QString text = QString(tr("Mouse")).append(" "); if ((wheelEve->angleDelta().y() >= 120)) { controlcode = 4; } else if ((wheelEve->angleDelta().y() <= -120)) { controlcode = 5; } else if ((wheelEve->angleDelta().x() >= 120)) { controlcode = 6; } else if ((wheelEve->angleDelta().x() <= -120)) { controlcode = 7; } if (controlcode > 0) { text = text.append(QString::number(controlcode)); setText(text); grabNextAction = false; grabbingWheel = false; edited = true; releaseMouse(); releaseKeyboard(); buttonslot.setSlotCode(controlcode); buttonslot.setSlotMode(JoyButtonSlot::JoyMouseButton); emit buttonCodeChanged(controlcode); } } else if (event->type() == QEvent::MouseButtonRelease) { QMouseEvent *mouseEve = static_cast(event); if (mouseEve->button() == Qt::LeftButton) { grabNextAction = true; setText("..."); setFocus(); grabKeyboard(); grabMouse(); } } return false; } void SimpleKeyGrabberButton::setValue(int value, int alias, JoyButtonSlot::JoySlotInputAction mode) { buttonslot.setSlotCode(value, alias); buttonslot.setSlotMode(mode); edited = true; setText(buttonslot.getSlotString()); } void SimpleKeyGrabberButton::setValue(int value, JoyButtonSlot::JoySlotInputAction mode) { buttonslot.setSlotCode(value); buttonslot.setSlotMode(mode); edited = true; setText(buttonslot.getSlotString()); } void SimpleKeyGrabberButton::setValue(QString value, JoyButtonSlot::JoySlotInputAction mode) { switch (mode) { case JoyButtonSlot::JoyLoadProfile: case JoyButtonSlot::JoyTextEntry: case JoyButtonSlot::JoyExecute: { buttonslot.setTextData(value); buttonslot.setSlotMode(mode); edited = true; break; } case JoyButtonSlot::JoyMix: { break; } default: { break; } } setText(buttonslot.getSlotString()); } void SimpleKeyGrabberButton::setValues(QString value, JoyButtonSlot::JoySlotInputAction mode) { switch (mode) { case JoyButtonSlot::JoyMix: { // buttonslot.setSlotCode(-1); buttonslot.setTextData(value); buttonslot.setSlotMode(JoyButtonSlot::JoyMix); edited = true; break; } default: { break; } } setText(buttonslot.getSlotString()); } void SimpleKeyGrabberButton::setValues(QString value, QList *jbtn, JoyButtonSlot::JoySlotInputAction mode) { switch (mode) { case JoyButtonSlot::JoyMix: { // buttonslot.setSlotCode(-1); buttonslot.setTextData(value); buttonslot.setSlotMode(JoyButtonSlot::JoyMix); buttonslot.setMixSlots(jbtn); edited = true; break; } default: { break; } } setText(buttonslot.getSlotString()); } JoyButtonSlot *SimpleKeyGrabberButton::getValue() { return &buttonslot; } JoyButtonSlot &SimpleKeyGrabberButton::getValueNonPointer() { return buttonslot; } void SimpleKeyGrabberButton::setValue(JoyButtonSlot *jbS) { buttonslot = jbS; } void SimpleKeyGrabberButton::refreshButtonLabel() { setText(buttonslot.getSlotString()); updateGeometry(); } bool SimpleKeyGrabberButton::isEdited() { return edited; } bool SimpleKeyGrabberButton::isGrabbing() { return grabNextAction; } AntiMicroX-antimicrox-b300273/src/simplekeygrabberbutton.h000066400000000000000000000043671471077622000237070ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SIMPLEKEYGRABBERBUTTON_H #define SIMPLEKEYGRABBERBUTTON_H #include "joybuttonslot.h" #include class QKeyEvent; class QEvent; class QWidget; class SimpleKeyGrabberButton : public QPushButton { Q_OBJECT public: explicit SimpleKeyGrabberButton(QWidget *parent = nullptr); void setValue(int value, int alias, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); // (.., unsigned) void setValue(int value, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); void setValue(QString value, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyLoadProfile); void setValues(QString value, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyMix); void setValues(QString value, QList *jbtn, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyMix); JoyButtonSlot *getValue(); JoyButtonSlot &getValueNonPointer(); void setValue(JoyButtonSlot *jbS); bool isEdited(); bool isGrabbing(); protected: virtual void keyPressEvent(QKeyEvent *event); virtual bool eventFilter(QObject *obj, QEvent *event); signals: void buttonCodeChanged(int value); public slots: void refreshButtonLabel(); private: bool grabNextAction; bool grabbingWheel; bool edited; JoyButtonSlot buttonslot; }; Q_DECLARE_METATYPE(SimpleKeyGrabberButton *) #endif // SIMPLEKEYGRABBERBUTTON_H AntiMicroX-antimicrox-b300273/src/springmousemoveinfo.h000066400000000000000000000026201471077622000232300ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SPRINGMOUSEMOVEINFO_H #define SPRINGMOUSEMOVEINFO_H namespace PadderCommon { typedef struct _springModeInfo { // Displacement of the X axis double displacementX; // Displacement of the Y axis double displacementY; // Width and height of the spring mode box int width; // unsigned int height; // unsigned // Should the cursor not move around the center // of the screen. bool relative; int screen; //-1 for default screen double springDeadX; double springDeadY; } springModeInfo; } // namespace PadderCommon #endif // SPRINGMOUSEMOVEINFO_H AntiMicroX-antimicrox-b300273/src/statisticsestimator.cpp000066400000000000000000000036671471077622000236030ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "statisticsestimator.h" StatisticsEstimator::StatisticsEstimator() { reset(); } /** * @brief Resets the StatisticsEstimator so that it is ready to process a new data stream. */ void StatisticsEstimator::reset() { m_mean = 0; m_var = 0; m_count = 0; } /** * @brief Processes a new sample of the current data stream and updates internal * intermediate values. */ void StatisticsEstimator::process(double x) { ++m_count; double dx = x - m_mean; m_mean += dx / m_count; double dx2 = x - m_mean; m_var += dx * dx2; } /** * @brief Calculates the sample variance of the processed data stream from * internal intermediate values. * @returns Sample variance */ double StatisticsEstimator::calculateVariance() const { return m_var / (m_count - 1); } /** * @brief Calculates the squared relative three sigma error range, i.e. the squared * estimation accuracy in percent, of the processed data stream from internal * intermediate values. Use the squared value to avoid expensive root calculation. * @returns Squared relative error range. */ double StatisticsEstimator::calculateRelativeErrorSq() const { return 9 * calculateVariance() / (m_count * m_mean * m_mean); } AntiMicroX-antimicrox-b300273/src/statisticsestimator.h000066400000000000000000000027241471077622000232410ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include /** * @brief Estimates mean of a data stream using Welford's algorithm and * calculates statistic properties. */ class StatisticsEstimator { public: StatisticsEstimator(); void reset(); void process(double x); /** * @brief Gets the amount of processed samples. * @returns Processed sample count. */ inline size_t getCount() const { return m_count; } /** * @brief Gets the mean of processed samples. * @returns Mean of processed samples. */ inline double getMean() const { return m_mean; } double calculateVariance() const; double calculateRelativeErrorSq() const; private: double m_mean; double m_var; size_t m_count; }; AntiMicroX-antimicrox-b300273/src/stickpushbuttongroup.cpp000066400000000000000000000152171471077622000240010ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "stickpushbuttongroup.h" #include "buttoneditdialog.h" #include "inputdevice.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joycontrolstick.h" #include "joycontrolstickbuttonpushbutton.h" #include "joycontrolstickeditdialog.h" #include "joycontrolstickpushbutton.h" #include #include #include StickPushButtonGroup::StickPushButtonGroup(JoyControlStick *stick, bool keypadUnlocked, bool displayNames, QWidget *parent) : QGridLayout(parent) { this->keypadUnlocked = keypadUnlocked; this->stick = stick; this->displayNames = displayNames; generateButtons(); changeButtonLayout(); connect(stick, &JoyControlStick::joyModeChanged, this, &StickPushButtonGroup::changeButtonLayout); } void StickPushButtonGroup::generateButtons() { JoyControlStickButtonPushButton *pushbutton = nullptr; upLeftButton = generateBtnToGrid(pushbutton, stick, JoyControlStick::StickLeftUp, 0, 0); upButton = generateBtnToGrid(pushbutton, stick, JoyControlStick::StickUp, 0, 1); upRightButton = generateBtnToGrid(pushbutton, stick, JoyControlStick::StickRightUp, 0, 2); leftButton = generateBtnToGrid(pushbutton, stick, JoyControlStick::StickLeft, 1, 0); stickWidget = new JoyControlStickPushButton(stick, displayNames, parentWidget()); stickWidget->setIcon( QIcon::fromTheme(QString::fromUtf8("games_config_options"), QIcon(":/images/actions/games_config_options.png"))); connect(stickWidget, &JoyControlStickPushButton::clicked, this, &StickPushButtonGroup::showStickDialog); addWidget(stickWidget, 1, 1); rightButton = generateBtnToGrid(pushbutton, stick, JoyControlStick::StickRight, 1, 2); downLeftButton = generateBtnToGrid(pushbutton, stick, JoyControlStick::StickLeftDown, 2, 0); downButton = generateBtnToGrid(pushbutton, stick, JoyControlStick::StickDown, 2, 1); downRightButton = generateBtnToGrid(pushbutton, stick, JoyControlStick::StickRightDown, 2, 2); } JoyControlStickButtonPushButton * StickPushButtonGroup::generateBtnToGrid(JoyControlStickButtonPushButton *pushbutton, JoyControlStick *stick, JoyStickDirectionsType::JoyStickDirections stickValue, int gridRow, int gridCol) { JoyControlStickButton *button = stick->getButtons()->value(stickValue); pushbutton = new JoyControlStickButtonPushButton(button, displayNames, parentWidget()); connect(pushbutton, &JoyControlStickButtonPushButton::clicked, this, [this, pushbutton] { openStickButtonDialog(pushbutton); }); button->establishPropertyUpdatedConnections(); connect(button, &JoyControlStickButton::slotsChanged, this, &StickPushButtonGroup::propogateSlotsChanged); addWidget(pushbutton, gridRow, gridCol); return pushbutton; } void StickPushButtonGroup::changeButtonLayout() { if ((stick->getJoyMode() == JoyControlStick::StandardMode) || (stick->getJoyMode() == JoyControlStick::EightWayMode) || (stick->getJoyMode() == JoyControlStick::FourWayCardinal)) { upButton->setVisible(true); downButton->setVisible(true); leftButton->setVisible(true); rightButton->setVisible(true); } else { upButton->setVisible(false); downButton->setVisible(false); leftButton->setVisible(false); rightButton->setVisible(false); } if ((stick->getJoyMode() == JoyControlStick::EightWayMode) || (stick->getJoyMode() == JoyControlStick::FourWayDiagonal)) { upLeftButton->setVisible(true); upRightButton->setVisible(true); downLeftButton->setVisible(true); downRightButton->setVisible(true); } else { upLeftButton->setVisible(false); upRightButton->setVisible(false); downLeftButton->setVisible(false); downRightButton->setVisible(false); } } void StickPushButtonGroup::propogateSlotsChanged() { emit buttonSlotChanged(); } JoyControlStick *StickPushButtonGroup::getStick() const { return stick; } void StickPushButtonGroup::openStickButtonDialog(JoyControlStickButtonPushButton *pushbutton) { ButtonEditDialog *dialog = new ButtonEditDialog(pushbutton->getButton(), stick->getParentSet()->getInputDevice(), keypadUnlocked, parentWidget()); dialog->show(); } void StickPushButtonGroup::showStickDialog() { JoyControlStickEditDialog *dialog = new JoyControlStickEditDialog(stick, keypadUnlocked, parentWidget()); dialog->show(); } void StickPushButtonGroup::toggleNameDisplay() { displayNames = !displayNames; upButton->toggleNameDisplay(); downButton->toggleNameDisplay(); leftButton->toggleNameDisplay(); rightButton->toggleNameDisplay(); upLeftButton->toggleNameDisplay(); upRightButton->toggleNameDisplay(); downLeftButton->toggleNameDisplay(); downRightButton->toggleNameDisplay(); stickWidget->toggleNameDisplay(); } bool StickPushButtonGroup::ifDisplayNames() const { return displayNames; } JoyControlStickButtonPushButton *StickPushButtonGroup::getUpButton() const { return upButton; } JoyControlStickButtonPushButton *StickPushButtonGroup::getDownButton() const { return downButton; } JoyControlStickButtonPushButton *StickPushButtonGroup::getLeftButton() const { return leftButton; } JoyControlStickButtonPushButton *StickPushButtonGroup::getRightButton() const { return rightButton; } JoyControlStickButtonPushButton *StickPushButtonGroup::getUpLeftButton() const { return upLeftButton; } JoyControlStickButtonPushButton *StickPushButtonGroup::getUpRightButton() const { return upRightButton; } JoyControlStickButtonPushButton *StickPushButtonGroup::getDownLeftButton() const { return downLeftButton; } JoyControlStickButtonPushButton *StickPushButtonGroup::getDownRightButton() const { return downRightButton; } JoyControlStickPushButton *StickPushButtonGroup::getStickWidget() const { return stickWidget; } AntiMicroX-antimicrox-b300273/src/stickpushbuttongroup.h000066400000000000000000000061051471077622000234420ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef STICKPUSHBUTTONGROUP_H #define STICKPUSHBUTTONGROUP_H #include "joycontrolstickdirectionstype.h" #include class JoyControlStick; class QWidget; class JoyControlStickButtonPushButton; class JoyControlStickPushButton; class StickPushButtonGroup : public QGridLayout { Q_OBJECT public: explicit StickPushButtonGroup(JoyControlStick *stick, bool keypadUnlocked, bool displayNames = false, QWidget *parent = nullptr); JoyControlStick *getStick() const; bool ifDisplayNames() const; JoyControlStickButtonPushButton *getUpButton() const; JoyControlStickButtonPushButton *getDownButton() const; JoyControlStickButtonPushButton *getLeftButton() const; JoyControlStickButtonPushButton *getRightButton() const; JoyControlStickButtonPushButton *getUpLeftButton() const; JoyControlStickButtonPushButton *getUpRightButton() const; JoyControlStickButtonPushButton *getDownLeftButton() const; JoyControlStickButtonPushButton *getDownRightButton() const; JoyControlStickPushButton *getStickWidget() const; protected: void generateButtons(); signals: void buttonSlotChanged(); public slots: void changeButtonLayout(); void toggleNameDisplay(); private slots: void propogateSlotsChanged(); void openStickButtonDialog(JoyControlStickButtonPushButton *pushbutton); void showStickDialog(); private: JoyControlStick *stick; bool displayNames; bool keypadUnlocked; JoyControlStickButtonPushButton *upButton; JoyControlStickButtonPushButton *downButton; JoyControlStickButtonPushButton *leftButton; JoyControlStickButtonPushButton *rightButton; JoyControlStickButtonPushButton *upLeftButton; JoyControlStickButtonPushButton *upRightButton; JoyControlStickButtonPushButton *downLeftButton; JoyControlStickButtonPushButton *downRightButton; JoyControlStickPushButton *stickWidget; JoyControlStickButtonPushButton *generateBtnToGrid(JoyControlStickButtonPushButton *pushbutton, JoyControlStick *stick, JoyStickDirectionsType::JoyStickDirections stickValue, int gridRow, int gridCol); }; #endif // STICKPUSHBUTTONGROUP_H AntiMicroX-antimicrox-b300273/src/uihelpers/000077500000000000000000000000001471077622000207415ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/uihelpers/advancebuttondialoghelper.cpp000066400000000000000000000054301471077622000266640ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "advancebuttondialoghelper.h" #include "joybuttontypes/joybutton.h" #include AdvanceButtonDialogHelper::AdvanceButtonDialogHelper(JoyButton *button, QObject *parent) : QObject(parent) { Q_ASSERT(button); this->button = button; } void AdvanceButtonDialogHelper::insertAssignedSlot(int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode) { button->eventReset(); button->insertAssignedSlot(code, alias, index, mode); } void AdvanceButtonDialogHelper::insertAssignedSlot(JoyButtonSlot *newSlot, int index, bool updateActiveString) { button->eventReset(); button->insertAssignedSlot(newSlot, index, updateActiveString); } void AdvanceButtonDialogHelper::setAssignedSlot(JoyButtonSlot *otherSlot, int index) { button->eventReset(); button->setAssignedSlot(otherSlot, index); } void AdvanceButtonDialogHelper::setAssignedSlot(int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode) { button->eventReset(); button->setAssignedSlot(code, alias, index, mode); } void AdvanceButtonDialogHelper::removeAssignedSlot(int index) { int j = 0; qDebug() << "Assigned list slots after joining"; for (auto el : *button->getAssignedSlots()) { qDebug() << j << ")"; qDebug() << "code: " << el->getSlotCode(); qDebug() << "mode: " << el->getSlotMode(); qDebug() << "string: " << el->getSlotString(); j++; } button->eventReset(); j = 0; qDebug() << "Assigned list slots after joining"; for (auto el : *button->getAssignedSlots()) { qDebug() << j << ")"; qDebug() << "code: " << el->getSlotCode(); qDebug() << "mode: " << el->getSlotMode(); qDebug() << "string: " << el->getSlotString(); j++; } button->removeAssignedSlot(index); } void AdvanceButtonDialogHelper::onlyReset() { button->eventReset(); } void AdvanceButtonDialogHelper::onlyRemoveAssignedSlot(int index) { button->removeAssignedSlot(index); } AntiMicroX-antimicrox-b300273/src/uihelpers/advancebuttondialoghelper.h000066400000000000000000000033441471077622000263330ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ADVANCEBUTTONDIALOGHELPER_H #define ADVANCEBUTTONDIALOGHELPER_H #include "joybuttonslot.h" class JoyButton; class AdvanceButtonDialogHelper : public QObject { Q_OBJECT public: explicit AdvanceButtonDialogHelper(JoyButton *button, QObject *parent = nullptr); protected: JoyButton *button; public slots: void setAssignedSlot(JoyButtonSlot *otherSlot, int index); void setAssignedSlot(int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); void insertAssignedSlot(int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); void insertAssignedSlot(JoyButtonSlot *newSlot, int index, bool updateActiveString); void removeAssignedSlot(int index); void onlyReset(); void onlyRemoveAssignedSlot(int index); }; #endif // ADVANCEBUTTONDIALOGHELPER_H AntiMicroX-antimicrox-b300273/src/uihelpers/buttoneditdialoghelper.cpp000066400000000000000000000036531471077622000262150ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "buttoneditdialoghelper.h" #include "joybuttontypes/joybutton.h" #include ButtonEditDialogHelper::ButtonEditDialogHelper(JoyButton *button, QObject *parent) : QObject(parent) { Q_ASSERT(button); this->button = button; } ButtonEditDialogHelper::ButtonEditDialogHelper(QObject *parent) : QObject(parent) { } void ButtonEditDialogHelper::setAssignedSlot(int code, JoyButtonSlot::JoySlotInputAction mode) { button->clearSlotsEventReset(false); button->setAssignedSlot(code, mode); } void ButtonEditDialogHelper::setAssignedSlot(int code, int alias, JoyButtonSlot::JoySlotInputAction mode) { button->clearSlotsEventReset(false); button->setAssignedSlot(code, alias, mode); } void ButtonEditDialogHelper::setAssignedSlot(int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode) { button->clearSlotsEventReset(false); button->setAssignedSlot(code, alias, index, mode); } void ButtonEditDialogHelper::setUseTurbo(bool useTurbo) { button->setUseTurbo(useTurbo); } void ButtonEditDialogHelper::setThisButton(JoyButton *btn) { Q_ASSERT(btn); button = btn; } AntiMicroX-antimicrox-b300273/src/uihelpers/buttoneditdialoghelper.h000066400000000000000000000032371471077622000256600ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BUTTONEDITDIALOGHELPER_H #define BUTTONEDITDIALOGHELPER_H #include "joybuttonslot.h" class JoyButton; class ButtonEditDialogHelper : public QObject { Q_OBJECT public: explicit ButtonEditDialogHelper(JoyButton *button, QObject *parent = nullptr); explicit ButtonEditDialogHelper(QObject *parent = nullptr); void setThisButton(JoyButton *btn); protected: JoyButton *button; public slots: void setAssignedSlot(int code, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); void setAssignedSlot(int code, int alias, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); void setAssignedSlot(int code, int alias, int index, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); void setUseTurbo(bool useTurbo); }; #endif // BUTTONEDITDIALOGHELPER_H AntiMicroX-antimicrox-b300273/src/uihelpers/dpadcontextmenuhelper.cpp000066400000000000000000000053451471077622000260560ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "dpadcontextmenuhelper.h" #include "joybuttonslot.h" #include #include #include DPadContextMenuHelper::DPadContextMenuHelper(JoyDPad *dpad, QObject *parent) : QObject(parent) { Q_ASSERT(dpad); this->dpad = dpad; } void DPadContextMenuHelper::setPendingSlots(QHash *tempSlots) { pendingSlots.clear(); QHashIterator iter(*tempSlots); while (iter.hasNext()) { iter.next(); JoyButtonSlot *slot = iter.value(); JoyDPadButton::JoyDPadDirections tempDir = iter.key(); pendingSlots.insert(tempDir, slot); } } void DPadContextMenuHelper::clearPendingSlots() { pendingSlots.clear(); } void DPadContextMenuHelper::setFromPendingSlots() { if (!getPendingSlots().isEmpty()) { QHashIterator iter(getPendingSlots()); while (iter.hasNext()) { iter.next(); JoyButtonSlot *slot = iter.value(); if (slot) { JoyDPadButton::JoyDPadDirections tempDir = iter.key(); JoyDPadButton *button = dpad->getJoyButton(tempDir); button->clearSlotsEventReset(false); button->setAssignedSlot(slot->getSlotCode(), slot->getSlotCodeAlias(), slot->getSlotMode()); slot->deleteLater(); } } } } void DPadContextMenuHelper::clearButtonsSlotsEventReset() { QHash *buttons = dpad->getButtons(); QHashIterator iter(*buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->clearSlotsEventReset(); } } QHash const &DPadContextMenuHelper::getPendingSlots() { return pendingSlots; } AntiMicroX-antimicrox-b300273/src/uihelpers/dpadcontextmenuhelper.h000066400000000000000000000027631471077622000255240ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DPADCONTEXTMENUHELPER_H #define DPADCONTEXTMENUHELPER_H #include "joydpad.h" class JoyButtonSlot; class DPadContextMenuHelper : public QObject { Q_OBJECT public: explicit DPadContextMenuHelper(JoyDPad *dpad, QObject *parent = nullptr); void setPendingSlots(QHash *tempSlots); void clearPendingSlots(); QHash const &getPendingSlots(); public slots: void setFromPendingSlots(); void clearButtonsSlotsEventReset(); private: JoyDPad *dpad; QHash pendingSlots; }; #endif // DPADCONTEXTMENUHELPER_H AntiMicroX-antimicrox-b300273/src/uihelpers/dpadeditdialoghelper.cpp000066400000000000000000000055611471077622000256120ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "dpadeditdialoghelper.h" #include "joybuttonslot.h" #include #include DPadEditDialogHelper::DPadEditDialogHelper(JoyDPad *dpad, QObject *parent) : QObject(parent) { Q_ASSERT(dpad); this->dpad = dpad; } void DPadEditDialogHelper::setPendingSlots(QHash *tempSlots) { pendingSlots.clear(); QHashIterator iter(*tempSlots); while (iter.hasNext()) { iter.next(); JoyButtonSlot *slot = iter.value(); JoyDPadButton::JoyDPadDirections tempDir = iter.key(); pendingSlots.insert(tempDir, slot); } } void DPadEditDialogHelper::clearPendingSlots() { pendingSlots.clear(); } void DPadEditDialogHelper::setFromPendingSlots() { if (!getPendingSlots().isEmpty()) { QHashIterator iter(getPendingSlots()); while (iter.hasNext()) { iter.next(); JoyButtonSlot *slot = iter.value(); if (slot) { JoyDPadButton::JoyDPadDirections tempDir = iter.key(); JoyDPadButton *button = dpad->getJoyButton(tempDir); button->clearSlotsEventReset(false); button->setAssignedSlot(slot->getSlotCode(), slot->getSlotCodeAlias(), slot->getSlotMode()); slot->deleteLater(); } } } } void DPadEditDialogHelper::clearButtonsSlotsEventReset() { QHash *buttons = dpad->getButtons(); QHashIterator iter(*buttons); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); button->clearSlotsEventReset(); } } void DPadEditDialogHelper::updateJoyDPadDelay(int value) { int temp = value * 10; if (dpad->getDPadDelay() != temp) { dpad->setDPadDelay(temp); } } QHash const &DPadEditDialogHelper::getPendingSlots() { return pendingSlots; } AntiMicroX-antimicrox-b300273/src/uihelpers/dpadeditdialoghelper.h000066400000000000000000000030261471077622000252510ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DPADEDITDIALOGHELPER_H #define DPADEDITDIALOGHELPER_H #include "joydpad.h" class JoyButtonSlot; class DPadEditDialogHelper : public QObject { Q_OBJECT public: explicit DPadEditDialogHelper(JoyDPad *dpad, QObject *parent = nullptr); void setPendingSlots(QHash *tempSlots); void clearPendingSlots(); QHash const &getPendingSlots(); public slots: void setFromPendingSlots(); void clearButtonsSlotsEventReset(); void updateJoyDPadDelay(int value); private: JoyDPad *dpad; QHash pendingSlots; }; #endif // DPADEDITDIALOGHELPER_H AntiMicroX-antimicrox-b300273/src/uihelpers/gamecontrollermappingdialoghelper.cpp000066400000000000000000000042441471077622000304220ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska . */ #include "gamecontrollermappingdialoghelper.h" #include "globalvariables.h" #include "inputdevice.h" #include GameControllerMappingDialogHelper::GameControllerMappingDialogHelper(InputDevice *device, QObject *parent) : QObject(parent) { this->device = device; } void GameControllerMappingDialogHelper::raiseDeadZones() { device->setRawAxisDeadZone(GlobalVariables::InputDevice::RAISEDDEADZONE); device->getActiveSetJoystick()->raiseAxesDeadZones(); } void GameControllerMappingDialogHelper::raiseDeadZones(int deadZone) { device->getActiveSetJoystick()->raiseAxesDeadZones(deadZone); device->setRawAxisDeadZone(deadZone); } void GameControllerMappingDialogHelper::setupDeadZones() { device->getActiveSetJoystick()->setIgnoreEventState(true); device->getActiveSetJoystick()->release(); device->getActiveSetJoystick()->currentAxesDeadZones(&originalAxesDeadZones); device->getActiveSetJoystick()->raiseAxesDeadZones(); device->setRawAxisDeadZone(GlobalVariables::InputDevice::RAISEDDEADZONE); } void GameControllerMappingDialogHelper::restoreDeviceDeadZones() { device->getActiveSetJoystick()->setIgnoreEventState(false); device->getActiveSetJoystick()->release(); device->getActiveSetJoystick()->setAxesDeadZones(&originalAxesDeadZones); device->setRawAxisDeadZone(GlobalVariables::InputDevice::RAISEDDEADZONE); } AntiMicroX-antimicrox-b300273/src/uihelpers/gamecontrollermappingdialoghelper.h000066400000000000000000000026061471077622000300670ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GAMECONTROLLERMAPPINGDIALOGHELPER_H #define GAMECONTROLLERMAPPINGDIALOGHELPER_H #include #include class InputDevice; class GameControllerMappingDialogHelper : public QObject { Q_OBJECT public: explicit GameControllerMappingDialogHelper(InputDevice *device, QObject *parent = nullptr); public slots: void raiseDeadZones(); void raiseDeadZones(int deadZone); void setupDeadZones(); void restoreDeviceDeadZones(); private: InputDevice *device; QList originalAxesDeadZones; }; #endif // GAMECONTROLLERMAPPINGDIALOGHELPER_H AntiMicroX-antimicrox-b300273/src/uihelpers/joyaxiscontextmenuhelper.cpp000066400000000000000000000034061471077622000266300ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joyaxiscontextmenuhelper.h" #include "joyaxis.h" #include JoyAxisContextMenuHelper::JoyAxisContextMenuHelper(JoyAxis *axis, QObject *parent) : QObject(parent) { Q_ASSERT(axis); this->axis = axis; } void JoyAxisContextMenuHelper::setNAssignedSlot(int code, int alias, JoyButtonSlot::JoySlotInputAction mode) { JoyButton *button = axis->getNAxisButton(); button->clearSlotsEventReset(false); button->setAssignedSlot(code, alias, mode); } void JoyAxisContextMenuHelper::setPAssignedSlot(int code, int alias, JoyButtonSlot::JoySlotInputAction mode) { JoyButton *button = axis->getPAxisButton(); button->clearSlotsEventReset(false); button->setAssignedSlot(code, alias, mode); } void JoyAxisContextMenuHelper::clearAndResetAxisButtons() { JoyAxisButton *nbutton = axis->getNAxisButton(); JoyAxisButton *pbutton = axis->getPAxisButton(); nbutton->clearSlotsEventReset(); pbutton->clearSlotsEventReset(); } AntiMicroX-antimicrox-b300273/src/uihelpers/joyaxiscontextmenuhelper.h000066400000000000000000000026531471077622000263000ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYAXISCONTEXTMENUHELPER_H #define JOYAXISCONTEXTMENUHELPER_H #include "joybuttonslot.h" class JoyAxis; class JoyAxisContextMenuHelper : public QObject { Q_OBJECT public: explicit JoyAxisContextMenuHelper(JoyAxis *axis, QObject *parent = nullptr); protected: JoyAxis *axis; public slots: void setNAssignedSlot(int code, int alias, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); void setPAssignedSlot(int code, int alias, JoyButtonSlot::JoySlotInputAction mode = JoyButtonSlot::JoyKeyboard); void clearAndResetAxisButtons(); }; #endif // JOYAXISCONTEXTMENUHELPER_H AntiMicroX-antimicrox-b300273/src/uihelpers/joycontrolstickcontextmenuhelper.cpp000066400000000000000000000061221471077622000304000ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joycontrolstickcontextmenuhelper.h" #include "joybuttonslot.h" #include "joybuttontypes/joycontrolstickbutton.h" #include #include JoyControlStickContextMenuHelper::JoyControlStickContextMenuHelper(JoyControlStick *stick, QObject *parent) : QObject(parent) { Q_ASSERT(stick); this->stick = stick; } void JoyControlStickContextMenuHelper::setPendingSlots( QHash *tempSlots) { pendingSlots.clear(); QHashIterator iter(*tempSlots); while (iter.hasNext()) { iter.next(); JoyButtonSlot *slot = iter.value(); JoyControlStick::JoyStickDirections tempDir = iter.key(); pendingSlots.insert(tempDir, slot); } } void JoyControlStickContextMenuHelper::clearPendingSlots() { pendingSlots.clear(); } void JoyControlStickContextMenuHelper::setFromPendingSlots() { if (!getPendingSlots().isEmpty()) { QHashIterator iter(getPendingSlots()); while (iter.hasNext()) { iter.next(); JoyButtonSlot *slot = iter.value(); if (slot) { JoyControlStick::JoyStickDirections tempDir = iter.key(); JoyControlStickButton *button = stick->getDirectionButton(tempDir); if (button) { button->clearSlotsEventReset(false); button->setAssignedSlot(slot->getSlotCode(), slot->getSlotCodeAlias(), slot->getSlotMode()); } slot->deleteLater(); } } } } void JoyControlStickContextMenuHelper::clearButtonsSlotsEventReset() { QHash *buttons = stick->getButtons(); QHashIterator iter(*buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button) { button->clearSlotsEventReset(); } } } QHash const &JoyControlStickContextMenuHelper::getPendingSlots() { return pendingSlots; } AntiMicroX-antimicrox-b300273/src/uihelpers/joycontrolstickcontextmenuhelper.h000066400000000000000000000032671471077622000300540ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYCONTROLSTICKCONTEXTMENUHELPER_H #define JOYCONTROLSTICKCONTEXTMENUHELPER_H #include "joycontrolstick.h" class JoyButtonSlot; /** * @brief Some helper methods which run in the IO thread and are called * from the GUI thread. */ class JoyControlStickContextMenuHelper : public QObject { Q_OBJECT public: explicit JoyControlStickContextMenuHelper(JoyControlStick *stick, QObject *parent = nullptr); void setPendingSlots(QHash *tempSlots); void clearPendingSlots(); QHash const &getPendingSlots(); public slots: void setFromPendingSlots(); void clearButtonsSlotsEventReset(); private: JoyControlStick *stick; QHash pendingSlots; }; #endif // JOYCONTROLSTICKCONTEXTMENUHELPER_H AntiMicroX-antimicrox-b300273/src/uihelpers/joycontrolstickeditdialoghelper.cpp000066400000000000000000000063551471077622000301440ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joycontrolstickeditdialoghelper.h" #include "joybuttonslot.h" #include "joybuttontypes/joycontrolstickbutton.h" #include JoyControlStickEditDialogHelper::JoyControlStickEditDialogHelper(JoyControlStick *stick, QObject *parent) : QObject(parent) { Q_ASSERT(stick); this->stick = stick; } void JoyControlStickEditDialogHelper::setPendingSlots(QHash *tempSlots) { pendingSlots.clear(); QHashIterator iter(*tempSlots); while (iter.hasNext()) { iter.next(); JoyButtonSlot *slot = iter.value(); JoyControlStick::JoyStickDirections tempDir = iter.key(); pendingSlots.insert(tempDir, slot); } } void JoyControlStickEditDialogHelper::clearPendingSlots() { pendingSlots.clear(); } void JoyControlStickEditDialogHelper::setFromPendingSlots() { if (!getPendingSlots().isEmpty()) { QHashIterator iter(getPendingSlots()); while (iter.hasNext()) { iter.next(); JoyButtonSlot *slot = iter.value(); if (slot) { JoyControlStick::JoyStickDirections tempDir = iter.key(); JoyControlStickButton *button = stick->getDirectionButton(tempDir); if (button) { button->clearSlotsEventReset(false); button->setAssignedSlot(slot->getSlotCode(), slot->getSlotCodeAlias(), slot->getSlotMode()); } slot->deleteLater(); } } } } void JoyControlStickEditDialogHelper::clearButtonsSlotsEventReset() { QHash *buttons = stick->getButtons(); QHashIterator iter(*buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button) { button->clearSlotsEventReset(); } } } void JoyControlStickEditDialogHelper::updateControlStickDelay(int value) { int temp = value * 10; if (stick->getStickDelay() != temp) { stick->setStickDelay(temp); } } QHash const &JoyControlStickEditDialogHelper::getPendingSlots() { return pendingSlots; } AntiMicroX-antimicrox-b300273/src/uihelpers/joycontrolstickeditdialoghelper.h000066400000000000000000000033361471077622000276050ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYCONTROLSTICKEDITDIALOGHELPER_H #define JOYCONTROLSTICKEDITDIALOGHELPER_H #include "joycontrolstick.h" class JoyButtonSlot; /** * @brief Some helper methods which run in the IO thread and are called * from the GUI thread. */ class JoyControlStickEditDialogHelper : public QObject { Q_OBJECT public: explicit JoyControlStickEditDialogHelper(JoyControlStick *stick, QObject *parent = nullptr); void setPendingSlots(QHash *tempSlots); void clearPendingSlots(); QHash const &getPendingSlots(); public slots: void setFromPendingSlots(); void clearButtonsSlotsEventReset(); void updateControlStickDelay(int value); private: JoyControlStick *stick; QHash pendingSlots; }; #endif // JOYCONTROLSTICKEDITDIALOGHELPER_H AntiMicroX-antimicrox-b300273/src/uihelpers/joysensoriothreadhelper.cpp000066400000000000000000000060601471077622000264220ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joysensoriothreadhelper.h" #include "joybuttonslot.h" #include "joybuttontypes/joysensorbutton.h" #include "joysensor.h" #include JoySensorIoThreadHelper::JoySensorIoThreadHelper(JoySensor *sensor, QObject *parent) : QObject(parent) , m_sensor(sensor) { Q_ASSERT(m_sensor); } /** * @brief Sets pending slot values * The values are applied to the buttons by calling setFromPendingSlots. * @param[in] tempSlots QHash of new pending slot values. * Buttons that are absent from the hash will be left unchanged. */ void JoySensorIoThreadHelper::setPendingSlots(QHash *tempSlots) { m_pending_slots.clear(); for (auto iter = tempSlots->cbegin(); iter != tempSlots->cend(); ++iter) { JoyButtonSlot *slot = iter.value(); JoySensorDirection tempDir = iter.key(); m_pending_slots.insert(tempDir, slot); } } /** * @brief Clears pending slot values */ void JoySensorIoThreadHelper::clearPendingSlots() { m_pending_slots.clear(); } /** * @brief Applies pending slot values to the buttons * Should be called via QMetaObject::invokeMethod */ void JoySensorIoThreadHelper::setFromPendingSlots() { if (!m_pending_slots.isEmpty()) { for (auto iter = m_pending_slots.cbegin(); iter != m_pending_slots.cend(); ++iter) { JoyButtonSlot *slot = iter.value(); if (slot) { JoySensorDirection tempDir = iter.key(); JoySensorButton *button = m_sensor->getDirectionButton(tempDir); if (button) { button->clearSlotsEventReset(false); button->setAssignedSlot(slot->getSlotCode(), slot->getSlotCodeAlias(), slot->getSlotMode()); } slot->deleteLater(); } } } } /** * @brief Calls JoyButton::clearSlotEventReset on all JoyButtons of the underlying sensor. * Should be called via QMetaObject::invokeMethod */ void JoySensorIoThreadHelper::clearButtonsSlotsEventReset() { QHash *buttons = m_sensor->getButtons(); for (auto iter = buttons->cbegin(); iter != buttons->cend(); ++iter) { JoySensorButton *button = iter.value(); if (button) button->clearSlotsEventReset(); } } AntiMicroX-antimicrox-b300273/src/uihelpers/joysensoriothreadhelper.h000066400000000000000000000026361471077622000260740ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2022 Max Maisel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "joysensordirection.h" #include #include class JoyButtonSlot; class JoySensor; /** * @brief Some helper methods which run in the IO thread and are called * from the GUI thread. */ class JoySensorIoThreadHelper : public QObject { Q_OBJECT public: explicit JoySensorIoThreadHelper(JoySensor *sensor, QObject *parent = nullptr); void setPendingSlots(QHash *tempSlots); void clearPendingSlots(); public slots: void setFromPendingSlots(); void clearButtonsSlotsEventReset(); private: JoySensor *m_sensor; QHash m_pending_slots; }; AntiMicroX-antimicrox-b300273/src/uihelpers/joytabwidgethelper.cpp000066400000000000000000000074611471077622000253510ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joytabwidgethelper.h" #include "inputdevice.h" #include "joybuttonslot.h" #include "joybuttontypes/joybutton.h" #include "logger.h" #include "xml/inputdevicexml.h" #include "xmlconfigreader.h" #include "xmlconfigwriter.h" #include JoyTabWidgetHelper::JoyTabWidgetHelper(InputDevice *device, QObject *parent) : QObject(parent) { Q_ASSERT(device); this->device = device; this->reader = nullptr; this->writer = nullptr; this->errorOccurred = false; } JoyTabWidgetHelper::~JoyTabWidgetHelper() { if (this->reader != nullptr) { delete this->reader; this->reader = nullptr; } if (this->writer != nullptr) { delete this->writer; this->writer = nullptr; } } bool JoyTabWidgetHelper::hasReader() { return (this->reader != nullptr); } XMLConfigReader *JoyTabWidgetHelper::getReader() { return this->reader; } bool JoyTabWidgetHelper::hasWriter() { return (this->writer != nullptr); } XMLConfigWriter *JoyTabWidgetHelper::getWriter() { return this->writer; } bool JoyTabWidgetHelper::hasError() { return errorOccurred; } QString JoyTabWidgetHelper::getErrorString() { return lastErrorString; } /** * @brief XML read entry point for the GUI */ bool JoyTabWidgetHelper::readConfigFile(QString filepath) { bool result = false; device->disconnectPropertyUpdatedConnection(); if (device->getActiveSetNumber() != 0) { device->setActiveSetNumber(0); } device->resetButtonDownCount(); if (this->reader != nullptr) { this->reader->deleteLater(); this->reader = nullptr; } this->reader = new XMLConfigReader; this->reader->setFileName(filepath); this->reader->configJoystick(device); device->establishPropertyUpdatedConnection(); result = !this->reader->hasError(); VERBOSE() << "Loading config file: " << filepath << (result ? " succeeded." : " failed."); return result; } bool JoyTabWidgetHelper::readConfigFileWithRevert(QString filepath) { device->revertProfileEdited(); return readConfigFile(filepath); } /** * @brief XML write entry point for the GUI */ bool JoyTabWidgetHelper::writeConfigFile(QString filepath) { bool result = false; if (this->writer != nullptr) { this->writer->deleteLater(); this->writer = nullptr; } this->writer = new XMLConfigWriter; this->writer->setFileName(filepath); InputDeviceXml *deviceXml = new InputDeviceXml(device); this->writer->write(deviceXml); delete deviceXml; result = !this->writer->hasError(); return result; } void JoyTabWidgetHelper::reInitDevice() { device->disconnectPropertyUpdatedConnection(); if (device->getActiveSetNumber() != 0) { device->setActiveSetNumber(0); } device->transferReset(); device->resetButtonDownCount(); device->reInitButtons(); device->establishPropertyUpdatedConnection(); } void JoyTabWidgetHelper::reInitDeviceWithRevert() { device->revertProfileEdited(); reInitDevice(); } AntiMicroX-antimicrox-b300273/src/uihelpers/joytabwidgethelper.h000066400000000000000000000032551471077622000250130ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYTABWIDGETHELPER_H #define JOYTABWIDGETHELPER_H #include class InputDevice; class XMLConfigReader; class XMLConfigWriter; class JoyTabWidgetHelper : public QObject { Q_OBJECT public: explicit JoyTabWidgetHelper(InputDevice *device, QObject *parent = nullptr); ~JoyTabWidgetHelper(); bool hasReader(); XMLConfigReader *getReader(); bool hasWriter(); XMLConfigWriter *getWriter(); bool hasError(); QString getErrorString(); protected: InputDevice *device; XMLConfigReader *reader; XMLConfigWriter *writer; bool errorOccurred; QString lastErrorString; public slots: bool readConfigFile(QString filepath); bool readConfigFileWithRevert(QString filepath); bool writeConfigFile(QString filepath); void reInitDevice(); void reInitDeviceWithRevert(); }; #endif // JOYTABWIDGETHELPER_H AntiMicroX-antimicrox-b300273/src/uinputhelper.cpp000066400000000000000000000356221471077622000222010ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "uinputhelper.h" UInputHelper *UInputHelper::_instance = nullptr; UInputHelper::UInputHelper(QObject *parent) : QObject(parent) { populateKnownAliases(); connect(qApp, &QApplication::aboutToQuit, this, &UInputHelper::deleteLater); } UInputHelper::~UInputHelper() { _instance = nullptr; } void UInputHelper::populateKnownAliases() { if (getKnownAliasesX11SymVK().isEmpty()) populateX11SymVk(knownAliasesX11SymVK); if (getKnownAliasesVKStrings().isEmpty()) populateXVkStrings(knownAliasesVKStrings); } void UInputHelper::populateX11SymVk(QHash &knownAliasesX11SymVK) { knownAliasesX11SymVK.insert("a", KEY_A); knownAliasesX11SymVK.insert("b", KEY_B); knownAliasesX11SymVK.insert("c", KEY_C); knownAliasesX11SymVK.insert("d", KEY_D); knownAliasesX11SymVK.insert("e", KEY_E); knownAliasesX11SymVK.insert("f", KEY_F); knownAliasesX11SymVK.insert("g", KEY_G); knownAliasesX11SymVK.insert("h", KEY_H); knownAliasesX11SymVK.insert("i", KEY_I); knownAliasesX11SymVK.insert("j", KEY_J); knownAliasesX11SymVK.insert("k", KEY_K); knownAliasesX11SymVK.insert("l", KEY_L); knownAliasesX11SymVK.insert("m", KEY_M); knownAliasesX11SymVK.insert("n", KEY_N); knownAliasesX11SymVK.insert("o", KEY_O); knownAliasesX11SymVK.insert("p", KEY_P); knownAliasesX11SymVK.insert("q", KEY_Q); knownAliasesX11SymVK.insert("r", KEY_R); knownAliasesX11SymVK.insert("s", KEY_S); knownAliasesX11SymVK.insert("t", KEY_T); knownAliasesX11SymVK.insert("u", KEY_U); knownAliasesX11SymVK.insert("v", KEY_V); knownAliasesX11SymVK.insert("w", KEY_W); knownAliasesX11SymVK.insert("x", KEY_X); knownAliasesX11SymVK.insert("y", KEY_Y); knownAliasesX11SymVK.insert("z", KEY_Z); knownAliasesX11SymVK.insert("Escape", KEY_ESC); knownAliasesX11SymVK.insert("F1", KEY_F1); knownAliasesX11SymVK.insert("F2", KEY_F2); knownAliasesX11SymVK.insert("F3", KEY_F3); knownAliasesX11SymVK.insert("F4", KEY_F4); knownAliasesX11SymVK.insert("F5", KEY_F5); knownAliasesX11SymVK.insert("F6", KEY_F6); knownAliasesX11SymVK.insert("F7", KEY_F7); knownAliasesX11SymVK.insert("F8", KEY_F8); knownAliasesX11SymVK.insert("F9", KEY_F9); knownAliasesX11SymVK.insert("F10", KEY_F10); knownAliasesX11SymVK.insert("F11", KEY_F11); knownAliasesX11SymVK.insert("F12", KEY_F12); knownAliasesX11SymVK.insert("F13", KEY_F13); knownAliasesX11SymVK.insert("F14", KEY_F14); knownAliasesX11SymVK.insert("F15", KEY_F15); knownAliasesX11SymVK.insert("F16", KEY_F16); knownAliasesX11SymVK.insert("F17", KEY_F17); knownAliasesX11SymVK.insert("F18", KEY_F18); knownAliasesX11SymVK.insert("F19", KEY_F19); knownAliasesX11SymVK.insert("F20", KEY_F20); knownAliasesX11SymVK.insert("F21", KEY_F21); knownAliasesX11SymVK.insert("F22", KEY_F22); knownAliasesX11SymVK.insert("F23", KEY_F23); knownAliasesX11SymVK.insert("F24", KEY_F24); knownAliasesX11SymVK.insert("grave", KEY_GRAVE); knownAliasesX11SymVK.insert("1", KEY_1); knownAliasesX11SymVK.insert("2", KEY_2); knownAliasesX11SymVK.insert("3", KEY_3); knownAliasesX11SymVK.insert("4", KEY_4); knownAliasesX11SymVK.insert("5", KEY_5); knownAliasesX11SymVK.insert("6", KEY_6); knownAliasesX11SymVK.insert("7", KEY_7); knownAliasesX11SymVK.insert("8", KEY_8); knownAliasesX11SymVK.insert("9", KEY_9); knownAliasesX11SymVK.insert("0", KEY_0); knownAliasesX11SymVK.insert("minus", KEY_MINUS); knownAliasesX11SymVK.insert("equal", KEY_EQUAL); knownAliasesX11SymVK.insert("BackSpace", KEY_BACKSPACE); knownAliasesX11SymVK.insert("Tab", KEY_TAB); knownAliasesX11SymVK.insert("bracketleft", KEY_LEFTBRACE); knownAliasesX11SymVK.insert("bracketright", KEY_RIGHTBRACE); knownAliasesX11SymVK.insert("backslash", KEY_BACKSLASH); knownAliasesX11SymVK.insert("Caps_Lock", KEY_CAPSLOCK); knownAliasesX11SymVK.insert("semicolon", KEY_SEMICOLON); knownAliasesX11SymVK.insert("apostrophe", KEY_APOSTROPHE); knownAliasesX11SymVK.insert("Return", KEY_ENTER); knownAliasesX11SymVK.insert("Shift_L", KEY_LEFTSHIFT); knownAliasesX11SymVK.insert("comma", KEY_COMMA); knownAliasesX11SymVK.insert("period", KEY_DOT); knownAliasesX11SymVK.insert("slash", KEY_SLASH); knownAliasesX11SymVK.insert("Control_L", KEY_LEFTCTRL); knownAliasesX11SymVK.insert("Super_L", KEY_LEFTMETA); knownAliasesX11SymVK.insert("Alt_L", KEY_LEFTALT); knownAliasesX11SymVK.insert("space", KEY_SPACE); knownAliasesX11SymVK.insert("Alt_R", KEY_RIGHTALT); knownAliasesX11SymVK.insert("Menu", KEY_COMPOSE); knownAliasesX11SymVK.insert("Control_R", KEY_RIGHTCTRL); knownAliasesX11SymVK.insert("Shift_R", KEY_RIGHTSHIFT); knownAliasesX11SymVK.insert("Up", KEY_UP); knownAliasesX11SymVK.insert("Left", KEY_LEFT); knownAliasesX11SymVK.insert("Down", KEY_DOWN); knownAliasesX11SymVK.insert("Right", KEY_RIGHT); knownAliasesX11SymVK.insert("Print", KEY_PRINT); knownAliasesX11SymVK.insert("Insert", KEY_INSERT); knownAliasesX11SymVK.insert("Delete", KEY_DELETE); knownAliasesX11SymVK.insert("Home", KEY_HOME); knownAliasesX11SymVK.insert("End", KEY_END); knownAliasesX11SymVK.insert("Prior", KEY_PAGEUP); knownAliasesX11SymVK.insert("Next", KEY_PAGEDOWN); knownAliasesX11SymVK.insert("Num_Lock", KEY_NUMLOCK); knownAliasesX11SymVK.insert("KP_Divide", KEY_KPSLASH); knownAliasesX11SymVK.insert("KP_Multiply", KEY_KPASTERISK); knownAliasesX11SymVK.insert("KP_Subtract", KEY_KPMINUS); knownAliasesX11SymVK.insert("KP_Add", KEY_KPPLUS); knownAliasesX11SymVK.insert("KP_Enter", KEY_KPENTER); knownAliasesX11SymVK.insert("KP_1", KEY_KP1); knownAliasesX11SymVK.insert("KP_2", KEY_KP2); knownAliasesX11SymVK.insert("KP_3", KEY_KP3); knownAliasesX11SymVK.insert("KP_4", KEY_KP4); knownAliasesX11SymVK.insert("KP_5", KEY_KP5); knownAliasesX11SymVK.insert("KP_6", KEY_KP6); knownAliasesX11SymVK.insert("KP_7", KEY_KP7); knownAliasesX11SymVK.insert("KP_8", KEY_KP8); knownAliasesX11SymVK.insert("KP_9", KEY_KP9); knownAliasesX11SymVK.insert("KP_0", KEY_KP0); knownAliasesX11SymVK.insert("KP_Decimal", KEY_KPDOT); knownAliasesX11SymVK.insert("Scroll_Lock", KEY_SCROLLLOCK); knownAliasesX11SymVK.insert("Pause", KEY_PAUSE); knownAliasesX11SymVK.insert("Multi_key", KEY_RIGHTALT); } void UInputHelper::populateXVkStrings(QHash &knownAliasesVKStrings) { knownAliasesVKStrings.insert(KEY_A, tr("a")); knownAliasesVKStrings.insert(KEY_B, tr("b")); knownAliasesVKStrings.insert(KEY_C, tr("c")); knownAliasesVKStrings.insert(KEY_D, tr("d")); knownAliasesVKStrings.insert(KEY_E, tr("e")); knownAliasesVKStrings.insert(KEY_F, tr("f")); knownAliasesVKStrings.insert(KEY_G, tr("g")); knownAliasesVKStrings.insert(KEY_H, tr("h")); knownAliasesVKStrings.insert(KEY_I, tr("i")); knownAliasesVKStrings.insert(KEY_J, tr("j")); knownAliasesVKStrings.insert(KEY_K, tr("k")); knownAliasesVKStrings.insert(KEY_L, tr("l")); knownAliasesVKStrings.insert(KEY_M, tr("m")); knownAliasesVKStrings.insert(KEY_N, tr("n")); knownAliasesVKStrings.insert(KEY_O, tr("o")); knownAliasesVKStrings.insert(KEY_P, tr("p")); knownAliasesVKStrings.insert(KEY_Q, tr("q")); knownAliasesVKStrings.insert(KEY_R, tr("r")); knownAliasesVKStrings.insert(KEY_S, tr("s")); knownAliasesVKStrings.insert(KEY_T, tr("t")); knownAliasesVKStrings.insert(KEY_U, tr("u")); knownAliasesVKStrings.insert(KEY_V, tr("v")); knownAliasesVKStrings.insert(KEY_W, tr("w")); knownAliasesVKStrings.insert(KEY_X, tr("x")); knownAliasesVKStrings.insert(KEY_Y, tr("y")); knownAliasesVKStrings.insert(KEY_Z, tr("z")); knownAliasesVKStrings.insert(KEY_ESC, tr("Esc")); knownAliasesVKStrings.insert(KEY_F1, tr("F1")); knownAliasesVKStrings.insert(KEY_F2, tr("F2")); knownAliasesVKStrings.insert(KEY_F3, tr("F3")); knownAliasesVKStrings.insert(KEY_F4, tr("F4")); knownAliasesVKStrings.insert(KEY_F5, tr("F5")); knownAliasesVKStrings.insert(KEY_F6, tr("F6")); knownAliasesVKStrings.insert(KEY_F7, tr("F7")); knownAliasesVKStrings.insert(KEY_F8, tr("F8")); knownAliasesVKStrings.insert(KEY_F9, tr("F9")); knownAliasesVKStrings.insert(KEY_F10, tr("F10")); knownAliasesVKStrings.insert(KEY_F11, tr("F11")); knownAliasesVKStrings.insert(KEY_F12, tr("F12")); knownAliasesVKStrings.insert(KEY_F13, tr("F13")); knownAliasesVKStrings.insert(KEY_F14, tr("F14")); knownAliasesVKStrings.insert(KEY_F15, tr("F15")); knownAliasesVKStrings.insert(KEY_F16, tr("F16")); knownAliasesVKStrings.insert(KEY_F17, tr("F17")); knownAliasesVKStrings.insert(KEY_F18, tr("F18")); knownAliasesVKStrings.insert(KEY_F19, tr("F19")); knownAliasesVKStrings.insert(KEY_F20, tr("F20")); knownAliasesVKStrings.insert(KEY_F21, tr("F21")); knownAliasesVKStrings.insert(KEY_F22, tr("F22")); knownAliasesVKStrings.insert(KEY_F23, tr("F23")); knownAliasesVKStrings.insert(KEY_F24, tr("F24")); knownAliasesVKStrings.insert(KEY_GRAVE, tr("`")); knownAliasesVKStrings.insert(KEY_1, tr("1")); knownAliasesVKStrings.insert(KEY_2, tr("2")); knownAliasesVKStrings.insert(KEY_3, tr("3")); knownAliasesVKStrings.insert(KEY_4, tr("4")); knownAliasesVKStrings.insert(KEY_5, tr("5")); knownAliasesVKStrings.insert(KEY_6, tr("6")); knownAliasesVKStrings.insert(KEY_7, tr("7")); knownAliasesVKStrings.insert(KEY_8, tr("8")); knownAliasesVKStrings.insert(KEY_9, tr("9")); knownAliasesVKStrings.insert(KEY_0, tr("0")); knownAliasesVKStrings.insert(KEY_MINUS, tr("-")); knownAliasesVKStrings.insert(KEY_EQUAL, tr("=")); knownAliasesVKStrings.insert(KEY_BACKSPACE, tr("BackSpace")); knownAliasesVKStrings.insert(KEY_TAB, tr("Tab")); knownAliasesVKStrings.insert(KEY_LEFTBRACE, tr("[")); knownAliasesVKStrings.insert(KEY_RIGHTBRACE, tr("]")); knownAliasesVKStrings.insert(KEY_BACKSLASH, tr("\\")); knownAliasesVKStrings.insert(KEY_CAPSLOCK, tr("CapsLock")); knownAliasesVKStrings.insert(KEY_SEMICOLON, tr(";")); knownAliasesVKStrings.insert(KEY_APOSTROPHE, tr("'")); knownAliasesVKStrings.insert(KEY_ENTER, tr("Enter")); knownAliasesVKStrings.insert(KEY_LEFTSHIFT, tr("Shift_L")); knownAliasesVKStrings.insert(KEY_COMMA, tr(",")); knownAliasesVKStrings.insert(KEY_DOT, tr(".")); knownAliasesVKStrings.insert(KEY_SLASH, tr("/")); knownAliasesVKStrings.insert(KEY_LEFTCTRL, tr("Ctrl_L")); knownAliasesVKStrings.insert(KEY_MENU, tr("Super_L")); knownAliasesVKStrings.insert(KEY_LEFTALT, tr("Alt_L")); knownAliasesVKStrings.insert(KEY_SPACE, tr("Space")); knownAliasesVKStrings.insert(KEY_RIGHTALT, tr("Alt_R")); knownAliasesVKStrings.insert(KEY_COMPOSE, tr("Menu")); knownAliasesVKStrings.insert(KEY_RIGHTCTRL, tr("Ctrl_R")); knownAliasesVKStrings.insert(KEY_RIGHTSHIFT, tr("Shift_R")); knownAliasesVKStrings.insert(KEY_UP, tr("Up")); knownAliasesVKStrings.insert(KEY_LEFT, tr("Left")); knownAliasesVKStrings.insert(KEY_DOWN, tr("Down")); knownAliasesVKStrings.insert(KEY_RIGHT, tr("Right")); knownAliasesVKStrings.insert(KEY_PRINT, tr("PrtSc")); knownAliasesVKStrings.insert(KEY_INSERT, tr("Ins")); knownAliasesVKStrings.insert(KEY_DELETE, tr("Del")); knownAliasesVKStrings.insert(KEY_HOME, tr("Home")); knownAliasesVKStrings.insert(KEY_END, tr("End")); knownAliasesVKStrings.insert(KEY_PAGEUP, tr("PgUp")); knownAliasesVKStrings.insert(KEY_PAGEDOWN, tr("PgDn")); knownAliasesVKStrings.insert(KEY_NUMLOCK, tr("NumLock")); knownAliasesVKStrings.insert(KEY_KPSLASH, tr("/")); knownAliasesVKStrings.insert(KEY_KPASTERISK, tr("*")); knownAliasesVKStrings.insert(KEY_KPMINUS, tr("-")); knownAliasesVKStrings.insert(KEY_KPPLUS, tr("+")); knownAliasesVKStrings.insert(KEY_KPENTER, tr("KP_Enter")); knownAliasesVKStrings.insert(KEY_KP1, tr("KP_1")); knownAliasesVKStrings.insert(KEY_KP2, tr("KP_2")); knownAliasesVKStrings.insert(KEY_KP3, tr("KP_3")); knownAliasesVKStrings.insert(KEY_KP4, tr("KP_4")); knownAliasesVKStrings.insert(KEY_KP5, tr("KP_5")); knownAliasesVKStrings.insert(KEY_KP6, tr("KP_6")); knownAliasesVKStrings.insert(KEY_KP7, tr("KP_7")); knownAliasesVKStrings.insert(KEY_KP8, tr("KP_8")); knownAliasesVKStrings.insert(KEY_KP9, tr("KP_9")); knownAliasesVKStrings.insert(KEY_KP0, tr("KP_0")); knownAliasesVKStrings.insert(KEY_SCROLLLOCK, tr("SCLK")); knownAliasesVKStrings.insert(KEY_PAUSE, tr("Pause")); knownAliasesVKStrings.insert(KEY_KPDOT, tr(".")); knownAliasesVKStrings.insert(KEY_LEFTMETA, tr("Super_L")); knownAliasesVKStrings.insert(KEY_RIGHTMETA, tr("Super_R")); knownAliasesVKStrings.insert(KEY_MUTE, tr("Mute")); knownAliasesVKStrings.insert(KEY_VOLUMEDOWN, tr("VolDn")); knownAliasesVKStrings.insert(KEY_VOLUMEUP, tr("VolUp")); knownAliasesVKStrings.insert(KEY_PLAYPAUSE, tr("Play")); knownAliasesVKStrings.insert(KEY_STOPCD, tr("Stop")); knownAliasesVKStrings.insert(KEY_PREVIOUSSONG, tr("Prev")); knownAliasesVKStrings.insert(KEY_NEXTSONG, tr("Next")); } UInputHelper *UInputHelper::getInstance() { if (!_instance) _instance = new UInputHelper(); return _instance; } void UInputHelper::deleteInstance() { if (_instance != nullptr) { delete _instance; _instance = nullptr; } } QString UInputHelper::getDisplayString(int virtualkey) { QString temp = QString(); if (virtualkey <= 0) temp = tr("[NO KEY]"); else if (getKnownAliasesVKStrings().contains(virtualkey)) temp = getKnownAliasesVKStrings().value(virtualkey); return temp; } int UInputHelper::getVirtualKey(QString codestring) { int temp = 0; if (getKnownAliasesX11SymVK().contains(codestring)) temp = getKnownAliasesX11SymVK().value(codestring); return temp; } QHash const &UInputHelper::getKnownAliasesX11SymVK() { return knownAliasesX11SymVK; } QHash const &UInputHelper::getKnownAliasesVKStrings() { return knownAliasesVKStrings; } AntiMicroX-antimicrox-b300273/src/uinputhelper.h000066400000000000000000000032401471077622000216350ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef UINPUTHELPER_H #define UINPUTHELPER_H #include #include #include class UInputHelper : public QObject { Q_OBJECT public: static UInputHelper *getInstance(); void deleteInstance(); QString getDisplayString(int virtualkey); int getVirtualKey(QString codestring); QHash const &getKnownAliasesX11SymVK(); QHash const &getKnownAliasesVKStrings(); protected: explicit UInputHelper(QObject *parent = nullptr); ~UInputHelper(); void populateKnownAliases(); static UInputHelper *_instance; QHash knownAliasesX11SymVK; QHash knownAliasesVKStrings; private: void populateXVkStrings(QHash &knownAliasesVKStrings); void populateX11SymVk(QHash &knownAliasesX11SymVK); }; #endif // UINPUTHELPER_H AntiMicroX-antimicrox-b300273/src/unixcapturewindowutility.cpp000066400000000000000000000073001471077622000246700ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "unixcapturewindowutility.h" #include "qtx11keymapper.h" #include #include #include #include // for XGrabPointer #include "x11extras.h" UnixCaptureWindowUtility::UnixCaptureWindowUtility(QObject *parent) : QObject(parent) { targetPath = ""; failed = false; targetWindow = None; } /** * @brief Attempt to capture window selected with the mouse */ void UnixCaptureWindowUtility::attemptWindowCapture() { // Only create instance when needed. static QtX11KeyMapper x11KeyMapper; targetPath = ""; targetWindow = None; failed = false; bool escaped = false; Cursor cursor; Window target_window = None; int status = 0; Display *display = nullptr; QString potentialXDisplayString = X11Extras::getInstance()->getXDisplayString(); if (!potentialXDisplayString.isEmpty()) { QByteArray tempByteArray = potentialXDisplayString.toLocal8Bit(); display = XOpenDisplay(tempByteArray.constData()); } else { display = XOpenDisplay(nullptr); } Window rootWin = XDefaultRootWindow(display); cursor = XCreateFontCursor(display, XC_crosshair); status = XGrabPointer(display, rootWin, False, ButtonPressMask, GrabModeSync, GrabModeAsync, None, cursor, CurrentTime); if (status == Success) { XGrabKey(display, XKeysymToKeycode(display, static_cast(x11KeyMapper.returnVirtualKey(Qt::Key_Escape))), 0, rootWin, true, GrabModeAsync, GrabModeAsync); XEvent event; XAllowEvents(display, SyncPointer, CurrentTime); XWindowEvent(display, rootWin, ButtonPressMask | KeyPressMask, &event); switch (event.type) { case (ButtonPress): target_window = event.xbutton.subwindow; if (target_window == None) target_window = event.xbutton.window; qDebug() << QString::number(target_window, 16); break; case (KeyPress): { escaped = true; break; } default: break; } XUngrabKey(display, XKeysymToKeycode(display, static_cast(x11KeyMapper.returnVirtualKey(Qt::Key_Escape))), 0, rootWin); XUngrabPointer(display, CurrentTime); XFlush(display); } if (target_window != None) targetWindow = target_window; else if (!escaped) failed = true; XCloseDisplay(display); emit captureFinished(); } /** * @brief Get the saved path for a window * @return Program path */ QString UnixCaptureWindowUtility::getTargetPath() const { return targetPath; } /** * @brief Check if attemptWindowCapture failed to obtain an application * @return Error status */ bool UnixCaptureWindowUtility::hasFailed() const { return failed; } long UnixCaptureWindowUtility::getTargetWindow() const { return targetWindow; } AntiMicroX-antimicrox-b300273/src/unixcapturewindowutility.h000066400000000000000000000025131471077622000243360ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef UNIXCAPTUREWINDOWUTILITY_H #define UNIXCAPTUREWINDOWUTILITY_H #include class UnixCaptureWindowUtility : public QObject { Q_OBJECT public: explicit UnixCaptureWindowUtility(QObject *parent = nullptr); QString getTargetPath() const; bool hasFailed() const; long getTargetWindow() const; signals: void captureFinished(); public slots: void attemptWindowCapture(); private: QString targetPath; bool failed; long targetWindow; }; #endif // UNIXCAPTUREWINDOWUTILITY_H AntiMicroX-antimicrox-b300273/src/vdpad.cpp000066400000000000000000000162151471077622000205500ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "vdpad.h" #include "globalvariables.h" #include VDPad::VDPad(int index, int originset, SetJoystick *parentSet, QObject *parent) : JoyDPad(index, originset, parentSet, parent) { this->upButton = nullptr; this->downButton = nullptr; this->leftButton = nullptr; this->rightButton = nullptr; pendingVDPadEvent = false; } VDPad::VDPad(JoyButton *upButton, JoyButton *downButton, JoyButton *leftButton, JoyButton *rightButton, int index, int originset, SetJoystick *parentSet, QObject *parent) : JoyDPad(index, originset, parentSet, parent) { this->upButton = upButton; upButton->setVDPad(this); this->downButton = downButton; downButton->setVDPad(this); this->leftButton = leftButton; leftButton->setVDPad(this); this->rightButton = rightButton; rightButton->setVDPad(this); pendingVDPadEvent = false; } VDPad::~VDPad() { if (!upButton.isNull()) { upButton->removeVDPad(); upButton = nullptr; } if (!downButton.isNull()) { downButton->removeVDPad(); downButton = nullptr; } if (!leftButton.isNull()) { leftButton->removeVDPad(); leftButton = nullptr; } if (!rightButton.isNull()) { rightButton->removeVDPad(); rightButton = nullptr; } } QString VDPad::getXmlName() { return GlobalVariables::VDPad::xmlName; } QString VDPad::getName(bool forceFullFormat, bool displayName) { QString label = QString(); if (!getDpadName().isEmpty() && displayName) { if (forceFullFormat) label.append(tr("VDPad")).append(" "); label.append(getDpadName()); } else if (!getDefaultDpadName().isEmpty()) { if (forceFullFormat) label.append(tr("VDPad")).append(" "); label.append(getDefaultDpadName()); } else { label.append(tr("VDPad")).append(" "); label.append(QString::number(getRealJoyNumber())); } return label; } void VDPad::joyEvent(bool pressed, bool ignoresets) { Q_UNUSED(pressed) int tempDirection = static_cast(JoyDPadButton::DpadCentered); // Check which buttons are currently active if ((upButton != nullptr) && upButton->getButtonState()) tempDirection |= JoyDPadButton::DpadUp; if (downButton && downButton->getButtonState()) tempDirection |= JoyDPadButton::DpadDown; if (leftButton && leftButton->getButtonState()) tempDirection |= JoyDPadButton::DpadLeft; if (rightButton && rightButton->getButtonState()) tempDirection |= JoyDPadButton::DpadRight; JoyDPad::joyEvent(tempDirection, ignoresets); pendingVDPadEvent = false; } void VDPad::addVButton(JoyDPadButton::JoyDPadDirections direction, JoyButton *button) { switch (direction) { case JoyDPadButton::DpadUp: { if (upButton != nullptr) upButton->removeVDPad(); upButton = button; upButton->setVDPad(this); break; } case JoyDPadButton::DpadDown: { if (downButton != nullptr) downButton->removeVDPad(); downButton = button; downButton->setVDPad(this); break; } case JoyDPadButton::DpadLeft: { if (leftButton != nullptr) leftButton->removeVDPad(); leftButton = button; leftButton->setVDPad(this); break; } case JoyDPadButton::DpadRight: { if (rightButton != nullptr) rightButton->removeVDPad(); rightButton = button; rightButton->setVDPad(this); break; } default: break; } } void VDPad::removeVButton(JoyDPadButton::JoyDPadDirections direction) { if ((direction == JoyDPadButton::DpadUp) && (upButton != nullptr)) { upButton->removeVDPad(); upButton = nullptr; } else if ((direction == JoyDPadButton::DpadDown) && (downButton != nullptr)) { downButton->removeVDPad(); downButton = nullptr; } else if ((direction == JoyDPadButton::DpadLeft) && (leftButton != nullptr)) { leftButton->removeVDPad(); leftButton = nullptr; } else if ((direction == JoyDPadButton::DpadRight) && (rightButton != nullptr)) { rightButton->removeVDPad(); rightButton = nullptr; } } void VDPad::removeVButton(JoyButton *button) { if ((button != nullptr) && (button == upButton)) { upButton->removeVDPad(); upButton = nullptr; } else if ((button != nullptr) && (button == downButton)) { downButton->removeVDPad(); downButton = nullptr; } else if ((button != nullptr) && (button == leftButton)) { leftButton->removeVDPad(); leftButton = nullptr; } else if ((button != nullptr) && (button == rightButton)) { rightButton->removeVDPad(); rightButton = nullptr; } } bool VDPad::isEmpty() { bool empty = true; if ((upButton != nullptr) || (downButton != nullptr) || (leftButton != nullptr) || (rightButton != nullptr)) { empty = false; } return empty; } JoyButton *VDPad::getVButton(JoyDPadButton::JoyDPadDirections direction) { JoyButton *button = nullptr; switch (direction) { case JoyDPadButton::DpadUp: { button = upButton; break; } case JoyDPadButton::DpadDown: { button = downButton; break; } case JoyDPadButton::DpadLeft: { button = leftButton; break; } case JoyDPadButton::DpadRight: { button = rightButton; break; } default: break; } return button; } bool VDPad::hasPendingEvent() { return pendingVDPadEvent; } void VDPad::queueJoyEvent(bool ignoresets) { Q_UNUSED(ignoresets) pendingVDPadEvent = true; } void VDPad::activatePendingEvent() { if (pendingVDPadEvent) { // Always use true. The proper direction value will be determined // in the joyEvent method. joyEvent(true); pendingVDPadEvent = false; } } void VDPad::clearPendingEvent() { pendingVDPadEvent = false; } JoyButton *VDPad::getUpButton() const { return upButton; } JoyButton *VDPad::getDownButton() const { return downButton; } JoyButton *VDPad::getLeftButton() const { return leftButton; } JoyButton *VDPad::getRightButton() const { return rightButton; } bool VDPad::getPendingVDPadEvent() const { return pendingVDPadEvent; } AntiMicroX-antimicrox-b300273/src/vdpad.h000066400000000000000000000043551471077622000202170ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef VDPAD_H #define VDPAD_H #include "joydpad.h" #include class VDPad : public JoyDPad { Q_OBJECT public: explicit VDPad(int index, int originset, SetJoystick *parentSet, QObject *parent); explicit VDPad(JoyButton *upButton, JoyButton *downButton, JoyButton *leftButton, JoyButton *rightButton, int index, int originset, SetJoystick *parentSet, QObject *parent); ~VDPad(); void joyEvent(bool pressed, bool ignoresets = false); void addVButton(JoyDPadButton::JoyDPadDirections direction, JoyButton *button); void removeVButton(JoyDPadButton::JoyDPadDirections direction); void removeVButton(JoyButton *button); JoyButton *getVButton(JoyDPadButton::JoyDPadDirections direction); bool isEmpty(); virtual QString getName(bool forceFullFormat = false, bool displayName = false) override; virtual QString getXmlName() override; void queueJoyEvent(bool ignoresets = false); bool hasPendingEvent(); void clearPendingEvent(); JoyButton *getUpButton() const; JoyButton *getDownButton() const; JoyButton *getLeftButton() const; JoyButton *getRightButton() const; bool getPendingVDPadEvent() const; public slots: void activatePendingEvent(); private: QPointer upButton; QPointer downButton; QPointer leftButton; QPointer rightButton; bool pendingVDPadEvent; }; #endif // VDPAD_H AntiMicroX-antimicrox-b300273/src/winextras.cpp000066400000000000000000000406041471077622000214750ustar00rootroot00000000000000#define _WIN32_WINNT 0x0600 #include #include #include #include #include #include #include #include #include "winextras.h" #include typedef DWORD(WINAPI *MYPROC)(HANDLE, DWORD, LPWSTR, PDWORD); // Check if QueryFullProcessImageNameW function exists in kernel32.dll. // Function does not exist in Windows XP. static MYPROC pQueryFullProcessImageNameW = (MYPROC)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "QueryFullProcessImageNameW"); const unsigned int WinExtras::EXTENDED_FLAG = 0x100; int WinExtras::originalMouseAccel = 0; static const QString ROOTASSOCIATIONKEY("HKEY_CURRENT_USER\\Software\\Classes"); static const QString FILEASSOCIATIONKEY(QString("%1\\%2").arg(ROOTASSOCIATIONKEY).arg(".amgp")); static const QString PROGRAMASSOCIATIONKEY(QString("%1\\%2").arg(ROOTASSOCIATIONKEY).arg("AntiMicro.amgp")); WinExtras WinExtras::_instance; WinExtras::WinExtras(QObject *parent) : QObject(parent) { populateKnownAliases(); } QString WinExtras::getDisplayString(unsigned int virtualkey) { QString temp; if (virtualkey <= 0) { temp = tr("[NO KEY]"); } else if (_instance.knownAliasesVKStrings.contains(virtualkey)) { temp = _instance.knownAliasesVKStrings.value(virtualkey); } return temp; } unsigned int WinExtras::getVirtualKey(QString codestring) { int temp = 0; if (_instance.knownAliasesX11SymVK.contains(codestring)) { temp = _instance.knownAliasesX11SymVK.value(codestring); } return temp; } void WinExtras::populateKnownAliases() { // These aliases are needed for xstrings that would // return empty space characters from XLookupString if (knownAliasesX11SymVK.isEmpty()) { knownAliasesX11SymVK.insert("Escape", VK_ESCAPE); knownAliasesX11SymVK.insert("Tab", VK_TAB); knownAliasesX11SymVK.insert("space", VK_SPACE); knownAliasesX11SymVK.insert("Delete", VK_DELETE); knownAliasesX11SymVK.insert("Return", VK_RETURN); knownAliasesX11SymVK.insert("KP_Enter", VK_RETURN); knownAliasesX11SymVK.insert("BackSpace", VK_BACK); knownAliasesX11SymVK.insert("F1", VK_F1); knownAliasesX11SymVK.insert("F2", VK_F2); knownAliasesX11SymVK.insert("F3", VK_F3); knownAliasesX11SymVK.insert("F4", VK_F4); knownAliasesX11SymVK.insert("F5", VK_F5); knownAliasesX11SymVK.insert("F6", VK_F6); knownAliasesX11SymVK.insert("F7", VK_F7); knownAliasesX11SymVK.insert("F8", VK_F8); knownAliasesX11SymVK.insert("F9", VK_F9); knownAliasesX11SymVK.insert("F10", VK_F10); knownAliasesX11SymVK.insert("F11", VK_F11); knownAliasesX11SymVK.insert("F12", VK_F12); knownAliasesX11SymVK.insert("Shift_L", VK_LSHIFT); knownAliasesX11SymVK.insert("Shift_R", VK_RSHIFT); knownAliasesX11SymVK.insert("Insert", VK_INSERT); knownAliasesX11SymVK.insert("Pause", VK_PAUSE); knownAliasesX11SymVK.insert("grave", VK_OEM_3); knownAliasesX11SymVK.insert("minus", VK_OEM_MINUS); knownAliasesX11SymVK.insert("equal", VK_OEM_PLUS); knownAliasesX11SymVK.insert("Caps_Lock", VK_CAPITAL); knownAliasesX11SymVK.insert("Control_L", VK_CONTROL); knownAliasesX11SymVK.insert("Control_R", VK_RCONTROL); knownAliasesX11SymVK.insert("Alt_L", VK_MENU); knownAliasesX11SymVK.insert("Alt_R", VK_RMENU); knownAliasesX11SymVK.insert("Super_L", VK_LWIN); knownAliasesX11SymVK.insert("Menu", VK_APPS); knownAliasesX11SymVK.insert("Prior", VK_PRIOR); knownAliasesX11SymVK.insert("Next", VK_NEXT); knownAliasesX11SymVK.insert("Home", VK_HOME); knownAliasesX11SymVK.insert("End", VK_END); knownAliasesX11SymVK.insert("Up", VK_UP); knownAliasesX11SymVK.insert("Down", VK_DOWN); knownAliasesX11SymVK.insert("Left", VK_LEFT); knownAliasesX11SymVK.insert("Right", VK_RIGHT); knownAliasesX11SymVK.insert("bracketleft", VK_OEM_4); knownAliasesX11SymVK.insert("bracketright", VK_OEM_6); knownAliasesX11SymVK.insert("backslash", VK_OEM_5); knownAliasesX11SymVK.insert("slash", VK_OEM_2); knownAliasesX11SymVK.insert("semicolon", VK_OEM_1); knownAliasesX11SymVK.insert("apostrophe", VK_OEM_7); knownAliasesX11SymVK.insert("comma", VK_OEM_COMMA); knownAliasesX11SymVK.insert("period", VK_OEM_PERIOD); knownAliasesX11SymVK.insert("KP_0", VK_NUMPAD0); knownAliasesX11SymVK.insert("KP_1", VK_NUMPAD1); knownAliasesX11SymVK.insert("KP_2", VK_NUMPAD2); knownAliasesX11SymVK.insert("KP_3", VK_NUMPAD3); knownAliasesX11SymVK.insert("KP_4", VK_NUMPAD4); knownAliasesX11SymVK.insert("KP_5", VK_NUMPAD5); knownAliasesX11SymVK.insert("KP_6", VK_NUMPAD6); knownAliasesX11SymVK.insert("KP_7", VK_NUMPAD7); knownAliasesX11SymVK.insert("KP_8", VK_NUMPAD8); knownAliasesX11SymVK.insert("KP_9", VK_NUMPAD9); knownAliasesX11SymVK.insert("Num_Lock", VK_NUMLOCK); knownAliasesX11SymVK.insert("KP_Divide", VK_DIVIDE); knownAliasesX11SymVK.insert("KP_Multiply", VK_MULTIPLY); knownAliasesX11SymVK.insert("KP_Subtract", VK_SUBTRACT); knownAliasesX11SymVK.insert("KP_Add", VK_ADD); knownAliasesX11SymVK.insert("KP_Decimal", VK_DECIMAL); knownAliasesX11SymVK.insert("Scroll_Lock", VK_SCROLL); knownAliasesX11SymVK.insert("Print", VK_SNAPSHOT); knownAliasesX11SymVK.insert("Multi_key", VK_RMENU); } if (knownAliasesVKStrings.isEmpty()) { knownAliasesVKStrings.insert(VK_LWIN, QObject::tr("Super")); knownAliasesVKStrings.insert(VK_APPS, QObject::tr("Menu")); knownAliasesVKStrings.insert(VK_VOLUME_MUTE, QObject::tr("Mute")); knownAliasesVKStrings.insert(VK_VOLUME_UP, QObject::tr("Vol+")); knownAliasesVKStrings.insert(VK_VOLUME_DOWN, QObject::tr("Vol-")); knownAliasesVKStrings.insert(VK_MEDIA_PLAY_PAUSE, QObject::tr("Play/Pause")); knownAliasesVKStrings.insert(VK_PLAY, QObject::tr("Play")); knownAliasesVKStrings.insert(VK_PAUSE, QObject::tr("Pause")); knownAliasesVKStrings.insert(VK_MEDIA_PREV_TRACK, QObject::tr("Prev")); knownAliasesVKStrings.insert(VK_MEDIA_NEXT_TRACK, QObject::tr("Next")); knownAliasesVKStrings.insert(VK_LAUNCH_MAIL, QObject::tr("Mail")); knownAliasesVKStrings.insert(VK_HOME, QObject::tr("Home")); knownAliasesVKStrings.insert(VK_LAUNCH_MEDIA_SELECT, QObject::tr("Media")); knownAliasesVKStrings.insert(VK_BROWSER_SEARCH, QObject::tr("Search")); } } /** * @brief Obtain a more specific virtual key (unsigned int) for a key grab event. * @param Scan code obtained from a key grab event * @param Virtual key obtained from a key grab event * @return Corrected virtual key as an unsigned int */ unsigned int WinExtras::correctVirtualKey(unsigned int scancode, unsigned int virtualkey) { int mapvirtual = MapVirtualKey(scancode, MAPVK_VSC_TO_VK_EX); int extended = (scancode & EXTENDED_FLAG) != 0; int finalvirtual = 0; switch (virtualkey) { case VK_CONTROL: finalvirtual = extended ? VK_RCONTROL : VK_LCONTROL; break; case VK_SHIFT: finalvirtual = mapvirtual; break; case VK_MENU: finalvirtual = extended ? VK_RMENU : VK_LMENU; break; case 0x5E: // Ignore System Reserved VK finalvirtual = 0; break; default: finalvirtual = virtualkey; } return finalvirtual; } /** * @brief Convert a virtual key into the corresponding keyboard scan code. * @param Windows virtual key * @param Qt key alias * @return Keyboard scan code as an unsigned int */ unsigned int WinExtras::scancodeFromVirtualKey(unsigned int virtualkey, unsigned int alias) { int scancode = 0; if (virtualkey == VK_PAUSE) { // MapVirtualKey does not work with VK_PAUSE scancode = 0x45; } else { scancode = MapVirtualKey(virtualkey, MAPVK_VK_TO_VSC); } switch (virtualkey) { case VK_LEFT: case VK_UP: case VK_RIGHT: case VK_DOWN: // arrow keys case VK_PRIOR: case VK_NEXT: // page up and page down case VK_END: case VK_HOME: case VK_INSERT: case VK_DELETE: case VK_DIVIDE: // numpad slash case VK_NUMLOCK: case VK_RCONTROL: case VK_RMENU: { scancode |= EXTENDED_FLAG; // set extended bit break; } case VK_RETURN: { // Remove ambiguity between Enter and Numpad Enter. // In Windows, VK_RETURN is used for both. if (alias == Qt::Key_Enter) { scancode |= EXTENDED_FLAG; // set extended bit break; } } } return scancode; } /** * @brief Check foreground window (window in focus) and obtain the * corresponding exe file path. * @return File path of executable */ QString WinExtras::getForegroundWindowExePath() { QString exePath; HWND foreground = GetForegroundWindow(); HANDLE windowProcess = NULL; if (foreground) { DWORD processId; GetWindowThreadProcessId(foreground, &processId); windowProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, true, processId); } if (windowProcess != NULL) { WCHAR filename[MAX_PATH]; if (pQueryFullProcessImageNameW) { // Windows Vista and later memset(filename, 0, sizeof(filename)); DWORD pathLength = MAX_PATH * sizeof(TCHAR); BOOL succeded = pQueryFullProcessImageNameW(windowProcess, 0, filename, &pathLength); if (!succeded) qWarning() << "pQueryFullProcessImageNameW returned: " << succeded; exePath = QString::fromWCharArray(filename); } else { qWarning() << "Windows XP is not supported"; } CloseHandle(windowProcess); } return exePath; } bool WinExtras::containsFileAssociationinRegistry() { bool result = false; QSettings associationReg(FILEASSOCIATIONKEY, QSettings::NativeFormat); QString temp = associationReg.value("Default", "").toString(); if (!temp.isEmpty()) { result = true; } return result; } void WinExtras::writeFileAssocationToRegistry() { QSettings fileAssociationReg(FILEASSOCIATIONKEY, QSettings::NativeFormat); fileAssociationReg.setValue("Default", "AntiMicro.amgp"); fileAssociationReg.sync(); QSettings programAssociationReg(PROGRAMASSOCIATIONKEY, QSettings::NativeFormat); programAssociationReg.setValue("Default", tr("AntiMicro Profile")); programAssociationReg.setValue( "shell/open/command/Default", QString("\"%1\" \"%2\"").arg(QDir::toNativeSeparators(qApp->applicationFilePath())).arg("%1")); programAssociationReg.setValue("DefaultIcon/Default", QString("%1,%2").arg(QDir::toNativeSeparators(qApp->applicationFilePath())).arg("0")); programAssociationReg.sync(); // Required to refresh settings used in Windows Explorer SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0); } void WinExtras::removeFileAssociationFromRegistry() { QSettings fileAssociationReg(FILEASSOCIATIONKEY, QSettings::NativeFormat); QString currentValue = fileAssociationReg.value("Default", "").toString(); if (currentValue == "AntiMicro.amgp") { fileAssociationReg.remove("Default"); fileAssociationReg.sync(); } QSettings programAssociationReg(PROGRAMASSOCIATIONKEY, QSettings::NativeFormat); programAssociationReg.remove(""); programAssociationReg.sync(); // Required to refresh settings used in Windows Explorer SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0); } // This functions works only with QT6 and newer C++ const wchar_t *convertCharArrayToLPCWSTR(const char *charArray) { wchar_t *wString = new wchar_t[1024]; MultiByteToWideChar(CP_ACP, 0, charArray, -1, wString, 1024); return wString; } /** * @brief Attempt to elevate process using runas * @return Execution status */ bool WinExtras::elevateAntiMicro() { QString antiProgramLocation = QDir::toNativeSeparators(qApp->applicationFilePath()); QByteArray temp = antiProgramLocation.toUtf8(); SHELLEXECUTEINFO sei = {sizeof(sei)}; char tempverb[6] = "runas"; QByteArray ba = antiProgramLocation.toLocal8Bit(); char *tempfile = ba.data(); tempverb[5] = '\0'; tempfile[antiProgramLocation.length()] = '\0'; #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) sei.lpVerb = convertCharArrayToLPCWSTR(tempverb); sei.lpFile = convertCharArrayToLPCWSTR(tempfile); #else sei.lpVerb = tempverb; sei.lpFile = tempfile; #endif sei.hwnd = NULL; sei.nShow = SW_NORMAL; BOOL result = ShellExecuteEx(&sei); return result; } /** * @brief Check if the application is running with administrative privileges. * @return Status indicating administrative privileges */ bool WinExtras::IsRunningAsAdmin() { BOOL isAdmin = FALSE; PSID administratorsGroup; SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY; isAdmin = AllocateAndInitializeSid(&ntAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &administratorsGroup); if (isAdmin) { if (!CheckTokenMembership(NULL, administratorsGroup, &isAdmin)) { isAdmin = FALSE; } FreeSid(administratorsGroup); } return isAdmin; } /** * @brief Temporarily disable "Enhanced Pointer Precision". */ void WinExtras::disablePointerPrecision() { int mouseInfo[3]; SystemParametersInfo(SPI_GETMOUSE, 0, &mouseInfo, 0); if (mouseInfo[2] == 1 && mouseInfo[2] == originalMouseAccel) { mouseInfo[2] = 0; SystemParametersInfo(SPI_SETMOUSE, 0, &mouseInfo, 0); } } /** * @brief If "Enhanced Pointer Precision" is currently disabled and * the setting has not been changed explicitly by the user while * the program has been running, re-enable "Enhanced Pointer Precision". * Return the mouse behavior to normal. */ void WinExtras::enablePointerPrecision() { int mouseInfo[3]; SystemParametersInfo(SPI_GETMOUSE, 0, &mouseInfo, 0); if (mouseInfo[2] == 0 && mouseInfo[2] != originalMouseAccel) { mouseInfo[2] = originalMouseAccel; SystemParametersInfo(SPI_SETMOUSE, 0, &mouseInfo, 0); } } /** * @brief Used to check if the "Enhance Pointer Precision" Windows * option is currently enabled. * @return Status of "Enhanced Pointer Precision" */ bool WinExtras::isUsingEnhancedPointerPrecision() { bool result = false; int mouseInfo[3]; SystemParametersInfo(SPI_GETMOUSE, 0, &mouseInfo, 0); if (mouseInfo[2] > 0) { result = true; } return result; } /** * @brief Get the value of "Enhanced Pointer Precision" when the program * first starts. Needed to not override setting if the option has * been disabled in Windows by the user. */ void WinExtras::grabCurrentPointerPrecision() { int mouseInfo[3]; SystemParametersInfo(SPI_GETMOUSE, 0, &mouseInfo, 0); originalMouseAccel = mouseInfo[2]; } /** * @brief Get the window text of the window currently in focus. * @return Window title of application in focus. */ QString WinExtras::getCurrentWindowText() { QString windowText; HWND foreground = GetForegroundWindow(); if (foreground != NULL) { wchar_t foundWindowTitle[256]; memset(foundWindowTitle, 0, sizeof(foundWindowTitle)); GetWindowTextW(foreground, foundWindowTitle, 255); QString temp = QString::fromWCharArray(foundWindowTitle); if (temp.isEmpty()) { memset(foundWindowTitle, 0, sizeof(foundWindowTitle)); SendMessageA(foreground, WM_GETTEXT, 255, (LPARAM)foundWindowTitle); temp = QString::fromWCharArray(foundWindowTitle); } if (!temp.isEmpty()) { windowText = temp; } } return windowText; } bool WinExtras::raiseProcessPriority() { bool result = false; result = SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); /*if (!result) { qDebug() << "COULD NOT RAISE PROCESS PRIORITY"; } */ return result; } QPoint WinExtras::getCursorPos() { POINT cursorPoint; GetCursorPos(&cursorPoint); QPoint temp(cursorPoint.x, cursorPoint.y); return temp; } AntiMicroX-antimicrox-b300273/src/winextras.h000066400000000000000000000026261471077622000211440ustar00rootroot00000000000000#ifndef WINEXTRAS_H #define WINEXTRAS_H #include #include #include #include class WinExtras : public QObject { Q_OBJECT public: static QString getDisplayString(unsigned int virtualkey); static unsigned int getVirtualKey(QString codestring); static unsigned int correctVirtualKey(unsigned int scancode, unsigned int virtualkey); static unsigned int scancodeFromVirtualKey(unsigned int virtualkey, unsigned int alias = 0); static const unsigned int EXTENDED_FLAG; static QString getForegroundWindowExePath(); static bool containsFileAssociationinRegistry(); static void writeFileAssocationToRegistry(); static void removeFileAssociationFromRegistry(); static bool IsRunningAsAdmin(); static bool elevateAntiMicro(); static void disablePointerPrecision(); static void enablePointerPrecision(); static bool isUsingEnhancedPointerPrecision(); static void grabCurrentPointerPrecision(); static QString getCurrentWindowText(); static bool raiseProcessPriority(); static QPoint getCursorPos(); protected: explicit WinExtras(QObject *parent = 0); void populateKnownAliases(); static WinExtras _instance; QHash knownAliasesX11SymVK; QHash knownAliasesVKStrings; static int originalMouseAccel; signals: public slots: }; #endif // WINEXTRAS_H AntiMicroX-antimicrox-b300273/src/x11extras.cpp000066400000000000000000000545731471077622000213230ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "common.h" #include "globalvariables.h" #include #include #include #include #include #include #include "x11extras.h" static QThreadStorage displays; X11Extras *X11Extras::_instance = nullptr; X11Extras::X11Extras(QObject *parent) : QObject(parent) , knownAliases() { _display = XOpenDisplay(nullptr); populateKnownAliases(); _instance = this; } /** * @brief Close display connection if one exists */ X11Extras::~X11Extras() { freeDisplay(); _instance = nullptr; } template void freeWindow(T *window) { if (window != nullptr) { XFree(window); window = nullptr; } } void X11Extras::freeDisplay() { if (_display != nullptr) { XCloseDisplay(_display); _display = nullptr; } } X11Extras *X11Extras::getInstance() { X11Extras *temp = nullptr; if (!displays.hasLocalData()) { qDebug() << "Displays don't have local data: create new instance of X11Extras"; temp = new X11Extras(); displays.setLocalData(temp); } else { qDebug() << "Display have local data"; temp = displays.localData(); } return temp; } void X11Extras::deleteInstance() { if (displays.hasLocalData()) { X11Extras *temp = displays.localData(); delete temp; displays.setLocalData(nullptr); } } const char *X11Extras::getEnvVariable(const char *var) const { const char *val = ::getenv(var); if (val == 0) { return ""; } else { return val; } } /** * @brief Get display instance * @return Display struct */ Display *X11Extras::display() { return _display; } bool X11Extras::hasValidDisplay() { return (_display != nullptr); } /** * @brief CURRENTLY NOT USED */ void X11Extras::closeDisplay() { freeDisplay(); } void X11Extras::setCustomDisplay(QString displayString) { GlobalVariables::X11Extras::_customDisplayString = displayString; } /** * @brief Return root window for a given X display * @param Screen number. If no value is passed, uses screen 1. * @return XID of the window */ unsigned long X11Extras::appRootWindow(int screen) { return (screen == -1) ? XDefaultRootWindow(display()) : XRootWindowOfScreen(XScreenOfDisplay(display(), screen)); } /** * @brief Get appropriate alias for a known KeySym string that might be blank * or contain invalid characters when returned from X. * @param QString representation of a KeySym string * @return Alias string or a blank QString if no alias was found */ QString X11Extras::getDisplayString(QString xcodestring) { QString temp = QString(); if (knownAliases.contains(xcodestring)) temp = knownAliases.value(xcodestring); return temp; } void X11Extras::populateKnownAliases() { // These aliases are needed for xstrings that would // return empty space characters from XLookupString if (knownAliases.isEmpty()) { knownAliases.insert("Escape", tr("ESC")); knownAliases.insert("Tab", tr("Tab")); knownAliases.insert("space", tr("Space")); knownAliases.insert("Delete", tr("DEL")); knownAliases.insert("Return", tr("Return")); knownAliases.insert("KP_Enter", tr("KP_Enter")); knownAliases.insert("BackSpace", tr("Backspace")); knownAliases.insert("ISO_Level3_Shift", tr("Alt Gr")); } } Window X11Extras::findParentClient(Window window) { Window parent = 0; Window root = 0; Window *children = 0; unsigned int num_children = 0; Window finalwindow = 0; Display *display = this->display(); if (windowIsViewable(display, window) && isWindowRelevant(display, window)) { finalwindow = window; } else { bool quitTraversal = false; while (!quitTraversal) { children = 0; if (XQueryTree(display, window, &root, &parent, &children, &num_children)) { if (children) { // must test for NULL XFree(children); } if (parent) { if (windowIsViewable(display, parent) && isWindowRelevant(display, parent)) { quitTraversal = true; finalwindow = parent; } else if (parent == 0) { quitTraversal = true; } else if (parent == root) { quitTraversal = true; } else { window = parent; } } else { quitTraversal = true; } } else { quitTraversal = true; } } } if (display != nullptr) qDebug() << "display in X11Extras::findParentClient(Window window) exists"; else qDebug() << "display in X11Extras::findParentClient(Window window) doesn't exist"; qDebug() << "parent: " << parent; qDebug() << "root: " << root; qDebug() << "num_children: " << num_children; qDebug() << "finalwindow: " << finalwindow; return finalwindow; } /** * @brief Check window and any parents for the window property "_NET_WM_PID" * @param Window XID for window of interest * @return PID of the application instance corresponding to the window */ int X11Extras::getApplicationPid(Window window) { Atom atom, actual_type; int actual_format = 0; unsigned long nitems = 0; unsigned long bytes_after = 0; unsigned char *prop = nullptr; int pid = 0; Window finalwindow = 0; Window parent = 0; Window root = 0; Window *children = nullptr; unsigned int num_children; Display *display = this->display(); atom = XInternAtom(display, "_NET_WM_PID", True); checkPropertyOnWin(windowHasProperty(display, window, atom), window, parent, finalwindow, root, children, display, num_children); if (finalwindow) { int status = 0; status = XGetWindowProperty(display, finalwindow, atom, 0, 1024, false, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop); if ((status == 0) && (prop != nullptr)) { pid = prop[2] << 16; pid += prop[1] << 8; pid += prop[0]; XFree(prop); } } return pid; } void X11Extras::checkPropertyOnWin(bool windowCorrected, Window &window, Window &parent, Window &finalwindow, Window &root, Window *children, Display *display, unsigned int &num_children) { if (windowCorrected) { finalwindow = window; } else { bool quitTraversal = false; while (!quitTraversal) { children = nullptr; if (XQueryTree(display, window, &root, &parent, &children, &num_children)) { if (children != nullptr) { // must be a test for NULL XFree(children); } if (parent) { if (windowCorrected) { quitTraversal = true; finalwindow = parent; } else if (parent == 0) { quitTraversal = true; } else if (parent == root) { quitTraversal = true; } else { window = parent; } } else { quitTraversal = true; } } else { quitTraversal = true; } } } } /** * @brief Find the application file location for a given PID * @param PID of window * @return File location of application */ QString X11Extras::getApplicationLocation(int pid) { QString exepath = QString(); if (pid > 0) { QString procString = QString("/proc/%1/exe").arg(pid); QFileInfo procFileInfo(procString); if (procFileInfo.exists()) { char buf[1024]; QByteArray tempByteArray = procString.toLocal8Bit(); ssize_t len = readlink(tempByteArray.constData(), buf, sizeof(buf) - 1); if (len != -1) buf[len] = '\0'; if (len > 0) { QString temp = QString::fromUtf8(buf); if (!temp.isEmpty()) exepath = temp; } } } return exepath; } /** * @brief Find the proper client window within a hierarchy. This check is needed * in some environments where the window that has been selected is actually * a child to a transparent parent window which was the one that was * actually grabbed * @param Top window to check * @return Client window XID or 0 if no appropriate window was found */ Window X11Extras::findClientWindow(Window window) { Window parent = 1; Window root = 0; Window *children = nullptr; unsigned int num_children = 0; Window finalwindow = 0; Display *display = this->display(); if (windowIsViewable(display, window) && isWindowRelevant(display, window)) { finalwindow = window; } else { XQueryTree(display, window, &root, &parent, &children, &num_children); if (children != nullptr) { for (unsigned int i = 0; (i < num_children) && !finalwindow; i++) { if (windowIsViewable(display, children[i]) && isWindowRelevant(display, window)) { finalwindow = children[i]; } } } if (!finalwindow && (children != nullptr)) { for (unsigned int i = 0; (i < num_children) && !finalwindow; i++) { finalwindow = findClientWindow(children[i]); } } freeWindow(children); } return finalwindow; } bool X11Extras::windowHasProperty(Display *display, Window window, Atom atom) { bool result = false; Atom actual_type; int actual_format = 0; unsigned long nitems = 0; unsigned long bytes_after = 0; unsigned char *prop = nullptr; int status = 0; status = XGetWindowProperty(display, window, atom, 0, 1024, false, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop); if ((status == Success) && (prop != nullptr)) { result = true; } freeWindow(prop); return result; } bool X11Extras::windowIsViewable(Display *display, Window window) { bool result = false; XWindowAttributes xwa; XGetWindowAttributes(display, window, &xwa); if ((xwa.c_class == InputOutput) && (xwa.map_state == IsViewable)) { result = true; } return result; } /** * @brief Go through a window's properties and search for an Atom * from a defined list. If an Atom is found in a window's properties, * that window should be considered relevant and one that should be grabbed. * @param Display* * @param Window * @return If a window has a relevant Atom in its properties. */ bool X11Extras::isWindowRelevant(Display *display, Window window) { bool result = false; QList temp; temp.append(XInternAtom(display, "WM_STATE", True)); temp.append(XInternAtom(display, "_NW_WM_STATE", True)); temp.append(XInternAtom(display, "_NW_WM_NAME", True)); QListIterator iter(temp); while (iter.hasNext()) { Atom current_atom = iter.next(); if (windowHasProperty(display, window, current_atom)) { iter.toBack(); result = true; } } return result; } QString X11Extras::getWindowTitle(Window window) { QString temp = QString(); Atom atom, actual_type; int actual_format = 0; unsigned long nitems = 0; unsigned long bytes_after = 0; unsigned char *prop = nullptr; int status = 0; qDebug() << "WIN: 0x" << QString::number(window, 16); Display *display = this->display(); Atom wm_name = XInternAtom(display, "WM_NAME", True); Atom net_wm_name = XInternAtom(display, "_NET_WM_NAME", True); atom = wm_name; QList tempList; tempList.append(wm_name); tempList.append(net_wm_name); QListIterator iter(tempList); while (iter.hasNext()) { Atom temp_atom = iter.next(); if (windowHasProperty(display, window, temp_atom)) { iter.toBack(); atom = temp_atom; } } status = XGetWindowProperty(display, window, atom, 0, 1024, false, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop); if ((status == Success) && (prop != nullptr)) { char *tempprop = reinterpret_cast(prop); temp.append(QString::fromUtf8(tempprop)); qDebug() << temp; } freeWindow(prop); return temp; } QString X11Extras::getWindowClass(Window window) { QString temp = QString(); Atom atom, actual_type; int actual_format = 0; unsigned long nitems = 0; unsigned long bytes_after = 0; unsigned char *prop = nullptr; int status = 0; Display *display = this->display(); atom = XInternAtom(display, "WM_CLASS", True); status = XGetWindowProperty(display, window, atom, 0, 1024, false, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop); if ((status == Success) && (prop != nullptr)) { qDebug() << nitems; char *null_char = strchr(reinterpret_cast(prop), '\0'); if ((null_char != nullptr) && (((reinterpret_cast(prop)) + nitems - 1) > null_char)) { *(null_char) = ' '; } char *tempprop = reinterpret_cast(prop); temp.append(QString::fromUtf8(tempprop)); qDebug() << temp; qDebug() << reinterpret_cast(prop); } freeWindow(prop); return temp; } unsigned long X11Extras::getWindowInFocus() { unsigned long result = 0; Window currentWindow = 0; int focusState = 0; Display *display = this->display(); if (display != nullptr) qDebug() << "display in X11Extras::getWindowInFocus() exists"; else qDebug() << "display in X11Extras::getWindowInFocus() doesn't exist"; XGetInputFocus(display, ¤tWindow, &focusState); if (currentWindow > 0) { result = static_cast(currentWindow); } qDebug() << "focusState of currentWindow: " << focusState; qDebug() << "result of currentWindow: " << result; return result; } /** * @brief Get QString representation of currently utilized X display. * @return */ QString X11Extras::getXDisplayString() { return GlobalVariables::X11Extras::_customDisplayString; } int X11Extras::getGroup1KeySym(int virtualkey) { Display *display = this->display(); int temp = XKeysymToKeycode(display, virtualkey); return XkbKeycodeToKeysym(display, temp, 0, 0); } void X11Extras::x11ResetMouseAccelerationChange(QString pointerName) { int xi_opcode, event, error; xi_opcode = event = error = 0; Display *display = this->display(); bool result = XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error); if (!result) { qInfo() << tr("xinput extension was not found. No mouse acceleration changes will occur."); } else { int ximajor = 2, ximinor = 0; if (XIQueryVersion(display, &ximajor, &ximinor) != Success) { qInfo() << tr("xinput version must be at least 2.0. No mouse acceleration changes will occur."); result = false; } } if (result) { XIDeviceInfo *all_devices = nullptr; XIDeviceInfo *current_devices = nullptr; XIDeviceInfo *mouse_device = nullptr; int num_devices = 0; all_devices = XIQueryDevice(display, XIAllDevices, &num_devices); findVirtualPtr(num_devices, current_devices, mouse_device, all_devices, pointerName); if (mouse_device != nullptr) { XDevice *device = XOpenDevice(display, static_cast(mouse_device->deviceid)); int num_feedbacks = 0; int feedback_id = -1; XFeedbackState *feedbacks = XGetFeedbackControl(display, device, &num_feedbacks); XFeedbackState *temp = feedbacks; checkFeedback(temp, num_feedbacks, feedback_id); XFree(feedbacks); if (feedback_id <= -1) { qInfo() << tr("PtrFeedbackClass was not found for virtual pointer." "No change to mouse acceleration will occur for device with id=%1") .arg(device->device_id); result = false; } else { qInfo() << tr("Changing mouse acceleration for device with id=%1").arg(device->device_id); XPtrFeedbackControl feedback; feedback.c_class = PtrFeedbackClass; feedback.length = sizeof(XPtrFeedbackControl); feedback.id = static_cast(feedback_id); feedback.threshold = 0; feedback.accelNum = 1; feedback.accelDenom = 1; XChangeFeedbackControl(display, device, DvAccelNum | DvAccelDenom | DvThreshold, reinterpret_cast(&feedback)); XSync(display, false); } XCloseDevice(display, device); } if (all_devices != nullptr) XIFreeDeviceInfo(all_devices); } } void X11Extras::x11ResetMouseAccelerationChange() { x11ResetMouseAccelerationChange(GlobalVariables::X11Extras::mouseDeviceName); } struct X11Extras::ptrInformation X11Extras::getPointInformation(QString pointerName) { struct ptrInformation tempInfo; int xi_opcode, event, error; xi_opcode = event = error = 0; Display *display = this->display(); bool result = XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error); if (result) { int ximajor = 2, ximinor = 0; if (XIQueryVersion(display, &ximajor, &ximinor) != Success) { qInfo() << QObject::tr("xinput version must be at least 2.0. No mouse acceleration changes will occur."); result = false; } } if (result) { XIDeviceInfo *all_devices = nullptr; XIDeviceInfo *current_devices = nullptr; XIDeviceInfo *mouse_device = nullptr; int num_devices = 0; all_devices = XIQueryDevice(display, XIAllDevices, &num_devices); findVirtualPtr(num_devices, current_devices, mouse_device, all_devices, pointerName); if (mouse_device != nullptr) { XDevice *device = XOpenDevice(display, static_cast(mouse_device->deviceid)); int num_feedbacks = 0; int feedback_id = -1; XFeedbackState *feedbacks = XGetFeedbackControl(display, device, &num_feedbacks); XFeedbackState *temp = feedbacks; checkFeedback(temp, num_feedbacks, feedback_id); if (feedback_id <= -1) { result = false; } else { XPtrFeedbackState *tempPtrFeedback = reinterpret_cast(temp); tempInfo.id = feedback_id; tempInfo.accelNum = tempPtrFeedback->accelNum; tempInfo.accelDenom = tempPtrFeedback->accelDenom; tempInfo.threshold = tempPtrFeedback->threshold; } XFree(feedbacks); XCloseDevice(display, device); } if (all_devices != nullptr) XIFreeDeviceInfo(all_devices); } return tempInfo; } void X11Extras::findVirtualPtr(int num_devices, XIDeviceInfo *current_devices, XIDeviceInfo *mouse_device, XIDeviceInfo *all_devices, QString pointerName) { for (int i = 0; i < num_devices; i++) { current_devices = &all_devices[i]; if ((current_devices->use == XISlavePointer) && (QString::fromUtf8(current_devices->name) == pointerName)) { mouse_device = current_devices; } } } void X11Extras::checkFeedback(XFeedbackState *temp, int &num_feedbacks, int &feedback_id) { for (int i = 0; (i < num_feedbacks) && (feedback_id == -1); i++) { if (temp->c_class == PtrFeedbackClass) { feedback_id = temp->id; } if ((i + 1) < num_feedbacks) { temp = (XFeedbackState *)((char *)temp + temp->length); } } } struct X11Extras::ptrInformation X11Extras::getPointInformation() { return getPointInformation(GlobalVariables::X11Extras::mouseDeviceName); } QPoint X11Extras::getPos() { XEvent mouseEvent; Window wid = DefaultRootWindow(display()); XWindowAttributes xwAttr; XQueryPointer(display(), wid, &mouseEvent.xbutton.root, &mouseEvent.xbutton.window, &mouseEvent.xbutton.x_root, &mouseEvent.xbutton.y_root, &mouseEvent.xbutton.x, &mouseEvent.xbutton.y, &mouseEvent.xbutton.state); XGetWindowAttributes(display(), wid, &xwAttr); QPoint currentPoint(mouseEvent.xbutton.x_root, mouseEvent.xbutton.y_root); return currentPoint; } QHash const &X11Extras::getKnownAliases() { return knownAliases; } AntiMicroX-antimicrox-b300273/src/x11extras.h000066400000000000000000000063721471077622000207620ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef X11EXTRAS_H #define X11EXTRAS_H #include #include #include #include #include class X11Extras : public QObject { Q_OBJECT public: struct ptrInformation { long id; int threshold; int accelNum; int accelDenom; ptrInformation() { id = -1; threshold = 0; accelNum = 0; accelDenom = 1; } }; ~X11Extras(); unsigned long appRootWindow(int screen = -1); Display *display(); bool hasValidDisplay(); QString getDisplayString(QString xcodestring); int getApplicationPid(Window window); QString getApplicationLocation(int pid); Window findClientWindow(Window window); Window findParentClient(Window window); void closeDisplay(); static QString getXDisplayString(); QString getWindowTitle(Window window); QString getWindowClass(Window window); unsigned long getWindowInFocus(); int getGroup1KeySym(int virtualkey); void x11ResetMouseAccelerationChange(); void x11ResetMouseAccelerationChange(QString pointerName); struct ptrInformation getPointInformation(); struct ptrInformation getPointInformation(QString pointerName); static void setCustomDisplay(QString displayString); const char *getEnvVariable(const char *var) const; static X11Extras *getInstance(); static void deleteInstance(); QHash const &getKnownAliases(); protected: explicit X11Extras(QObject *parent = nullptr); void populateKnownAliases(); bool windowHasProperty(Display *display, Window window, Atom atom); bool windowIsViewable(Display *display, Window window); bool isWindowRelevant(Display *display, Window window); static X11Extras *_instance; public slots: QPoint getPos(); private: void checkPropertyOnWin(bool windowCorrected, Window &window, Window &parent, Window &finalwindow, Window &root, Window *children, Display *display, unsigned int &num_children); void freeDisplay(); void checkFeedback(XFeedbackState *temp, int &num_feedbacks, int &feedback_id); void findVirtualPtr(int num_devices, XIDeviceInfo *current_devices, XIDeviceInfo *mouse_device, XIDeviceInfo *all_devices, QString pointerName); QHash knownAliases; Display *_display; }; #endif // X11EXTRAS_H AntiMicroX-antimicrox-b300273/src/xml/000077500000000000000000000000001471077622000175415ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/src/xml/inputdevicexml.cpp000066400000000000000000000770021471077622000233130ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "inputdevicexml.h" #include "inputdevice.h" #include "joybuttontypes/joycontrolstickbutton.h" #include "joybuttontypes/joysensorbutton.h" #include "joycontrolstick.h" #include "joysensor.h" #include "vdpad.h" #include "common.h" #include "globalvariables.h" #include "logger.h" #include #include #include InputDeviceXml::InputDeviceXml(InputDevice *inputDevice, QObject *parent) : QObject(parent) , m_inputDevice(inputDevice) { QThread *thread = m_inputDevice->thread(); this->moveToThread(thread); connect(this, &InputDeviceXml::readConfigSig, this, &InputDeviceXml::readConfig); } /** * @brief Deserializes the given XML stream into an InputDevice object * @param[in] xml The XML stream to read from */ void InputDeviceXml::readConfig(QXmlStreamReader *xml) { m_mutex_read_config.try_lock(); // reading of config should be handled in inputEventThread if (this->thread() != QThread::currentThread()) { emit readConfigSig(xml); DEBUG() << "Redirecting readConfig call to antoher Thread, waiting on mutex here."; bool opened = m_mutex_read_config.tryLock(1000); if (opened) DEBUG() << "readConfig mutex opened"; else WARN() << "Could not open mutex_read_config"; m_mutex_read_config.unlock(); return; } if (xml->isStartElement() && (xml->name().toString() == m_inputDevice->getXmlName())) { m_inputDevice->transferReset(); xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != m_inputDevice->getXmlName()))) { if ((xml->name().toString() == "sets") && xml->isStartElement()) { xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != "sets"))) { if ((xml->name().toString() == "set") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); index = index - 1; if ((index >= 0) && (index < m_inputDevice->getJoystick_sets().size())) m_inputDevice->getJoystick_sets().value(index)->readConfig(xml); } else { // If none of the above, skip the element xml->skipCurrentElement(); } xml->readNextStartElement(); } } else if ((xml->name().toString() == "stickAxisAssociation") && xml->isStartElement()) { int stickIndex = xml->attributes().value("index").toString().toInt(); int xAxis = xml->attributes().value("xAxis").toString().toInt(); int yAxis = xml->attributes().value("yAxis").toString().toInt(); if ((stickIndex > 0) && (xAxis > 0) && (yAxis > 0)) { xAxis -= 1; yAxis -= 1; stickIndex -= 1; QList setsList = m_inputDevice->getJoystick_sets().values(); for (QList::iterator setJoy = setsList.begin(); setJoy != setsList.end(); setJoy++) { int i = setJoy - setsList.begin(); JoyAxis *axis1 = (*setJoy)->getJoyAxis(xAxis); JoyAxis *axis2 = (*setJoy)->getJoyAxis(yAxis); if ((axis1 != nullptr) && (axis2 != nullptr)) { JoyControlStick *stick = new JoyControlStick(axis1, axis2, stickIndex, i, m_inputDevice); (*setJoy)->addControlStick(stickIndex, stick); } } xml->readNext(); } else { xml->skipCurrentElement(); } } else if ((xml->name().toString() == "vdpadButtonAssociations") && xml->isStartElement()) { int vdpadIndex = xml->attributes().value("index").toString().toInt(); if (vdpadIndex > 0) { QList setsList = m_inputDevice->getJoystick_sets().values(); for (QList::iterator setJoy = setsList.begin(); setJoy != setsList.end(); setJoy++) { int i = setJoy - setsList.begin(); VDPad *vdpad = (*setJoy)->getVDPad(vdpadIndex - 1); if (vdpad == nullptr) { vdpad = new VDPad(vdpadIndex - 1, i, *setJoy, *setJoy); (*setJoy)->addVDPad(vdpadIndex - 1, vdpad); } } xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != "vdpadButtonAssociations"))) { if ((xml->name().toString() == "vdpadButtonAssociation") && xml->isStartElement()) { int vdpadAxisIndex = xml->attributes().value("axis").toString().toInt(); int vdpadButtonIndex = xml->attributes().value("button").toString().toInt(); int vdpadDirection = xml->attributes().value("direction").toString().toInt(); if ((vdpadAxisIndex > 0) && (vdpadDirection > 0)) { vdpadAxisIndex -= 1; QList setsListJoy = m_inputDevice->getJoystick_sets().values(); for (QList::iterator setJoyCur = setsListJoy.begin(); setJoyCur != setsListJoy.end(); setJoyCur++) { VDPad *vdpad = (*setJoyCur)->getVDPad(vdpadIndex - 1); if (vdpad != nullptr) { JoyAxis *axis = (*setJoyCur)->getJoyAxis(vdpadAxisIndex); if (axis != nullptr) { JoyButton *button = nullptr; if (vdpadButtonIndex == 0) button = axis->getNAxisButton(); else if (vdpadButtonIndex == 1) button = axis->getPAxisButton(); if (button != nullptr) vdpad->addVButton( static_cast(vdpadDirection), button); } } } } else if ((vdpadButtonIndex > 0) && (vdpadDirection > 0)) { vdpadButtonIndex -= 1; QList setsListJoy = m_inputDevice->getJoystick_sets().values(); for (QList::iterator setJoyCur = setsListJoy.begin(); setJoyCur != setsListJoy.end(); setJoyCur++) { VDPad *vdpad = (*setJoyCur)->getVDPad(vdpadIndex - 1); if (vdpad != nullptr) { JoyButton *button = (*setJoyCur)->getJoyButton(vdpadButtonIndex); if (button != nullptr) vdpad->addVButton(static_cast(vdpadDirection), button); } } } xml->readNext(); } else { xml->skipCurrentElement(); } xml->readNextStartElement(); } } QList setJoys = m_inputDevice->getJoystick_sets().values(); for (QList::iterator currJoy = setJoys.begin(); currJoy != setJoys.end(); currJoy++) { QList VDPadLists = (*currJoy)->getVdpads().values(); for (QList::iterator currVDPad = VDPadLists.begin(); currVDPad != VDPadLists.end(); currVDPad++) { if (((*currVDPad) != nullptr) && (*currVDPad)->isEmpty()) (*currJoy)->removeVDPad(currVDPad - VDPadLists.begin()); } } } else if ((xml->name().toString() == "names") && xml->isStartElement()) { xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != "names"))) { if ((xml->name().toString() == "buttonname") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); QString temp = xml->readElementText(); index = index - 1; if ((index >= 0) && !temp.isEmpty()) { m_inputDevice->setButtonName(index, temp); } } else if ((xml->name().toString() == "axisbuttonname") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); int buttonIndex = xml->attributes().value("button").toString().toInt(); QString temp = xml->readElementText(); index = index - 1; buttonIndex = buttonIndex - 1; if ((index >= 0) && !temp.isEmpty()) { m_inputDevice->setAxisButtonName(index, buttonIndex, temp); } } else if ((xml->name().toString() == "controlstickbuttonname") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); int buttonIndex = xml->attributes().value("button").toString().toInt(); QString temp = xml->readElementText(); index = index - 1; if ((index >= 0) && !temp.isEmpty()) { m_inputDevice->setStickButtonName(index, buttonIndex, temp); } } else if ((xml->name().toString() == "sensorbuttonname") && xml->isStartElement()) { int type = xml->attributes().value("type").toString().toInt(); int direction = xml->attributes().value("button").toString().toInt(); QString temp = xml->readElementText(); if (!temp.isEmpty()) m_inputDevice->setSensorButtonName(static_cast(type), static_cast(direction), temp); } else if ((xml->name().toString() == "dpadbuttonname") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); int buttonIndex = xml->attributes().value("button").toString().toInt(); QString temp = xml->readElementText(); index = index - 1; if ((index >= 0) && !temp.isEmpty()) { m_inputDevice->setDPadButtonName(index, buttonIndex, temp); } } else if ((xml->name().toString() == "vdpadbuttonname") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); int buttonIndex = xml->attributes().value("button").toString().toInt(); QString temp = xml->readElementText(); index = index - 1; if ((index >= 0) && !temp.isEmpty()) { m_inputDevice->setVDPadButtonName(index, buttonIndex, temp); } } else if ((xml->name().toString() == "axisname") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); QString temp = xml->readElementText(); index = index - 1; if ((index >= 0) && !temp.isEmpty()) { m_inputDevice->setAxisName(index, temp); } } else if ((xml->name().toString() == "controlstickname") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); QString temp = xml->readElementText(); index = index - 1; if ((index >= 0) && !temp.isEmpty()) { m_inputDevice->setStickName(index, temp); } } else if ((xml->name().toString() == "sensorname") && xml->isStartElement()) { int type = xml->attributes().value("type").toString().toInt(); QString temp = xml->readElementText(); if (!temp.isEmpty()) m_inputDevice->setSensorName(static_cast(type), temp); } else if ((xml->name().toString() == "dpadname") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); QString temp = xml->readElementText(); index = index - 1; if ((index >= 0) && !temp.isEmpty()) { m_inputDevice->setDPadName(index, temp); } } else if ((xml->name().toString() == "vdpadname") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); QString temp = xml->readElementText(); index = index - 1; if ((index >= 0) && !temp.isEmpty()) { m_inputDevice->setVDPadName(index, temp); } } else { // If none of the above, skip the element xml->skipCurrentElement(); } xml->readNextStartElement(); } } else if ((xml->name().toString() == "calibration") && xml->isStartElement()) { m_inputDevice->getCalibrationBackend()->readConfig(xml); m_inputDevice->getCalibrationBackend()->applyCalibrations(); } else if ((xml->name().toString() == "keyPressTime") && xml->isStartElement()) { int tempchoice = xml->readElementText().toInt(); if (tempchoice >= 10) { m_inputDevice->setDeviceKeyPressTime(tempchoice); } } else if ((xml->name().toString() == "profilename") && xml->isStartElement()) { m_inputDevice->setProfileName(xml->readElementText()); } else { // If none of the above, skip the element xml->skipCurrentElement(); } xml->readNextStartElement(); } m_inputDevice->reInitButtons(); } m_mutex_read_config.unlock(); } /** * @brief Serializes an InputDevice object into the the given XML stream * @param[in,out] xml The XML stream to write to */ void InputDeviceXml::writeConfig(QXmlStreamWriter *xml) { xml->writeStartElement(m_inputDevice->getXmlName()); xml->writeAttribute("configversion", QString::number(PadderCommon::LATESTCONFIGFILEVERSION)); xml->writeAttribute("appversion", PadderCommon::programVersion); xml->writeComment("The SDL name for a joystick is included for informational purposes only."); xml->writeTextElement("sdlname", m_inputDevice->getSDLName()); xml->writeComment("The Unique ID for a joystick is included for informational purposes only."); xml->writeTextElement("uniqueID", m_inputDevice->getUniqueIDString()); // xml->writeTextElement("guid", m_inputDevice->getGUIDString()); if (!m_inputDevice->getProfileName().isEmpty()) xml->writeTextElement("profilename", m_inputDevice->getProfileName()); QListIterator currJoyStick(m_inputDevice->getActiveSetJoystick()->getSticks().values()); while (currJoyStick.hasNext()) { JoyControlStick *stick = currJoyStick.next(); xml->writeStartElement("stickAxisAssociation"); xml->writeAttribute("index", QString::number(stick->getRealJoyIndex())); xml->writeAttribute("xAxis", QString::number(stick->getAxisX()->getRealJoyIndex())); xml->writeAttribute("yAxis", QString::number(stick->getAxisY()->getRealJoyIndex())); xml->writeEndElement(); } // write vdpadButtonAssociations QListIterator currVDPad(m_inputDevice->getActiveSetJoystick()->getVdpads().values()); while (currVDPad.hasNext()) { VDPad *vdpad = currVDPad.next(); xml->writeStartElement("vdpadButtonAssociations"); xml->writeAttribute("index", QString::number(vdpad->getRealJoyNumber())); JoyButton *button = vdpad->getVButton(JoyDPadButton::DpadUp); if (button != nullptr) { xml->writeStartElement("vdpadButtonAssociation"); if (typeid(*button) == typeid(JoyAxisButton)) { JoyAxisButton *axisbutton = qobject_cast(button); xml->writeAttribute("axis", QString::number(axisbutton->getAxis()->getRealJoyIndex())); xml->writeAttribute("button", QString::number(button->getJoyNumber())); } else { xml->writeAttribute("axis", QString::number(0)); xml->writeAttribute("button", QString::number(button->getRealJoyNumber())); } xml->writeAttribute("direction", QString::number(JoyDPadButton::DpadUp)); xml->writeEndElement(); } button = vdpad->getVButton(JoyDPadButton::DpadDown); if (button != nullptr) { xml->writeStartElement("vdpadButtonAssociation"); if (typeid(*button) == typeid(JoyAxisButton)) { JoyAxisButton *axisbutton = qobject_cast(button); xml->writeAttribute("axis", QString::number(axisbutton->getAxis()->getRealJoyIndex())); xml->writeAttribute("button", QString::number(button->getJoyNumber())); } else { xml->writeAttribute("axis", QString::number(0)); xml->writeAttribute("button", QString::number(button->getRealJoyNumber())); } xml->writeAttribute("direction", QString::number(JoyDPadButton::DpadDown)); xml->writeEndElement(); } button = vdpad->getVButton(JoyDPadButton::DpadLeft); if (button != nullptr) { xml->writeStartElement("vdpadButtonAssociation"); if (typeid(*button) == typeid(JoyAxisButton)) { JoyAxisButton *axisbutton = qobject_cast(button); xml->writeAttribute("axis", QString::number(axisbutton->getAxis()->getRealJoyIndex())); xml->writeAttribute("button", QString::number(button->getJoyNumber())); } else { xml->writeAttribute("axis", QString::number(0)); xml->writeAttribute("button", QString::number(button->getRealJoyNumber())); } xml->writeAttribute("direction", QString::number(JoyDPadButton::DpadLeft)); xml->writeEndElement(); } button = vdpad->getVButton(JoyDPadButton::DpadRight); if (button != nullptr) { xml->writeStartElement("vdpadButtonAssociation"); if (typeid(*button) == typeid(JoyAxisButton)) { JoyAxisButton *axisbutton = qobject_cast(button); xml->writeAttribute("axis", QString::number(axisbutton->getAxis()->getRealJoyIndex())); xml->writeAttribute("button", QString::number(button->getJoyNumber())); } else { xml->writeAttribute("axis", QString::number(0)); xml->writeAttribute("button", QString::number(button->getRealJoyNumber())); } xml->writeAttribute("direction", QString::number(JoyDPadButton::DpadRight)); xml->writeEndElement(); } xml->writeEndElement(); } bool tempHasNames = m_inputDevice->elementsHaveNames(); if (tempHasNames) { xml->writeStartElement("names"); // // write buttons of joystick QListIterator currJoyBtn(m_inputDevice->getActiveSetJoystick()->getButtons().values()); while (currJoyBtn.hasNext()) { JoyButton *button = currJoyBtn.next(); if ((button != nullptr) && !button->getButtonName().isEmpty()) { xml->writeStartElement("buttonname"); xml->writeAttribute("index", QString::number(button->getRealJoyNumber())); xml->writeCharacters(button->getButtonName()); xml->writeEndElement(); } } // write axes of joystick QListIterator currentAxis(m_inputDevice->getActiveSetJoystick()->getAxes()->values()); while (currentAxis.hasNext()) { JoyAxis *axis = currentAxis.next(); if (axis != nullptr) { if (!axis->getAxisName().isEmpty()) { xml->writeStartElement("axisname"); xml->writeAttribute("index", QString::number(axis->getRealJoyIndex())); xml->writeCharacters(axis->getAxisName()); xml->writeEndElement(); } // write button of axis (with negative values) JoyAxisButton *naxisbutton = axis->getNAxisButton(); if (!naxisbutton->getButtonName().isEmpty()) { xml->writeStartElement("axisbuttonname"); xml->writeAttribute("index", QString::number(axis->getRealJoyIndex())); xml->writeAttribute("button", QString::number(naxisbutton->getRealJoyNumber())); xml->writeCharacters(naxisbutton->getButtonName()); xml->writeEndElement(); } // write button of axis (with positive values) JoyAxisButton *paxisbutton = axis->getPAxisButton(); if (!paxisbutton->getButtonName().isEmpty()) { xml->writeStartElement("axisbuttonname"); xml->writeAttribute("index", QString::number(axis->getRealJoyIndex())); xml->writeAttribute("button", QString::number(paxisbutton->getRealJoyNumber())); xml->writeCharacters(paxisbutton->getButtonName()); xml->writeEndElement(); } } } // write sticks QListIterator currStick(m_inputDevice->getActiveSetJoystick()->getSticks().values()); while (currStick.hasNext()) { JoyControlStick *stick = currStick.next(); if (stick != nullptr) { if (!stick->getStickName().isEmpty()) { xml->writeStartElement("controlstickname"); xml->writeAttribute("index", QString::number(stick->getRealJoyIndex())); xml->writeCharacters(stick->getStickName()); xml->writeEndElement(); } // write button of each stick QHash *buttons = stick->getButtons(); QHashIterator iter(*buttons); while (iter.hasNext()) { JoyControlStickButton *button = iter.next().value(); if (button && !button->getButtonName().isEmpty()) { xml->writeStartElement("controlstickbuttonname"); xml->writeAttribute("index", QString::number(stick->getRealJoyIndex())); xml->writeAttribute("button", QString::number(button->getRealJoyNumber())); xml->writeCharacters(button->getButtonName()); xml->writeEndElement(); } } } } // write sensors auto sensors = m_inputDevice->getActiveSetJoystick()->getSensors(); for (const auto &sensor : sensors) { if (sensor != nullptr) { if (!sensor->getSensorName().isEmpty()) { xml->writeStartElement("sensorname"); xml->writeAttribute("type", QString::number(sensor->getType())); xml->writeCharacters(sensor->getSensorName()); xml->writeEndElement(); } // write button of each sensor auto buttons = sensor->getButtons(); for (auto iter = buttons->cbegin(); iter != buttons->cend(); ++iter) { JoySensorButton *button = iter.value(); if (button && !button->getButtonName().isEmpty()) { xml->writeStartElement("sensorbuttonname"); xml->writeAttribute("type", QString::number(sensor->getType())); xml->writeAttribute("button", QString::number(button->getRealJoyNumber())); xml->writeCharacters(button->getButtonName()); xml->writeEndElement(); } } } } // write Hats QListIterator currJoyDPad(m_inputDevice->getActiveSetJoystick()->getHats().values()); while (currJoyDPad.hasNext()) { JoyDPad *dpad = currJoyDPad.next(); if (dpad != nullptr) { if (!dpad->getDpadName().isEmpty()) { xml->writeStartElement("dpadname"); xml->writeAttribute("index", QString::number(dpad->getRealJoyNumber())); xml->writeCharacters(dpad->getDpadName()); xml->writeEndElement(); } // write buttons of each Hat QHash *temp = dpad->getButtons(); QHashIterator iter(*temp); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); if (button && !button->getButtonName().isEmpty()) { xml->writeStartElement("dpadbuttonname"); xml->writeAttribute("index", QString::number(dpad->getRealJoyNumber())); xml->writeAttribute("button", QString::number(button->getRealJoyNumber())); xml->writeCharacters(button->getButtonName()); xml->writeEndElement(); } } } } // write VDPads QListIterator currVDPad(m_inputDevice->getActiveSetJoystick()->getVdpads().values()); while (currVDPad.hasNext()) { VDPad *vdpad = currVDPad.next(); if (vdpad != nullptr) { if (!vdpad->getDpadName().isEmpty()) { xml->writeStartElement("vdpadname"); xml->writeAttribute("index", QString::number(vdpad->getRealJoyNumber())); xml->writeCharacters(vdpad->getDpadName()); xml->writeEndElement(); } // write buttons of each VDPad QHash *temp = vdpad->getButtons(); QHashIterator iter(*temp); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); if ((button != nullptr) && !button->getButtonName().isEmpty()) { xml->writeStartElement("vdpadbutton"); xml->writeAttribute("index", QString::number(vdpad->getRealJoyNumber())); xml->writeAttribute("button", QString::number(button->getRealJoyNumber())); xml->writeCharacters(button->getButtonName()); xml->writeEndElement(); } } } } xml->writeEndElement(); // } if ((m_inputDevice->getDeviceKeyPressTime() > 0) && (m_inputDevice->getDeviceKeyPressTime() != GlobalVariables::InputDevice::DEFAULTKEYPRESSTIME)) xml->writeTextElement("keyPressTime", QString::number(m_inputDevice->getDeviceKeyPressTime())); m_inputDevice->getCalibrationBackend()->writeConfig(xml); xml->writeStartElement("sets"); for (const auto &joyset : m_inputDevice->getJoystick_sets()) { if (!joyset->isSetEmpty()) joyset->writeConfig(xml); else qDebug() << "Set is empty"; } xml->writeEndElement(); xml->writeEndElement(); } AntiMicroX-antimicrox-b300273/src/xml/inputdevicexml.h000066400000000000000000000034661471077622000227630ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef INPUTDEVICEXML_H #define INPUTDEVICEXML_H #include #include class QXmlStreamReader; class QXmlStreamWriter; class InputDevice; class AntiMicroSettings; /** * @brief Generic InputDevice XML serialization/deserialization helper class * Reads data from the supplied InputDevice object and writes it to XML or * reads data from an QXmlStreamReader and writes it to the InputDevice object. * * After serializing or deserializing the device data, it reads/writes * all SetJoysticks. */ class InputDeviceXml : public QObject { Q_OBJECT public: explicit InputDeviceXml(InputDevice *inputDevice, QObject *parent = nullptr); public slots: void readConfig(QXmlStreamReader *xml); // InputDeviceXml class void writeConfig(QXmlStreamWriter *xml); // InputDeviceXml class signals: void readConfigSig(QXmlStreamReader *xml); private: InputDevice *m_inputDevice; // ensures that readConfig returns when reading is finished even for reading in different thread QMutex m_mutex_read_config; }; #endif // INPUTDEVICEXML_H AntiMicroX-antimicrox-b300273/src/xml/joyaxisxml.cpp000066400000000000000000000143751471077622000224660ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joyaxisxml.h" #include "haptictriggerps5.h" #include "inputdevice.h" #include "joyaxis.h" #include "joybuttontypes/joyaxisbutton.h" #include "xml/joybuttonxml.h" #include #include #include JoyAxisXml::JoyAxisXml(JoyAxis *axis, QObject *parent) : QObject(parent) { m_joyAxis = axis; joyButtonXmlNAxis = new JoyButtonXml(axis->getNAxisButton()); joyButtonXmlPAxis = new JoyButtonXml(axis->getPAxisButton()); } JoyAxisXml::~JoyAxisXml() { if (!joyButtonXmlNAxis.isNull()) joyButtonXmlNAxis->deleteLater(); if (!joyButtonXmlPAxis.isNull()) joyButtonXmlPAxis->deleteLater(); } void JoyAxisXml::readConfig(QXmlStreamReader *xml) { if (xml->isStartElement() && (xml->name().toString() == m_joyAxis->getXmlName())) { xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != m_joyAxis->getXmlName()))) { bool found = readMainConfig(xml); if (!found && (xml->name().toString() == m_joyAxis->getNAxisButton()->getXmlName()) && xml->isStartElement()) { found = true; readButtonConfig(xml); } if (!found) xml->skipCurrentElement(); xml->readNextStartElement(); } } } void JoyAxisXml::writeConfig(QXmlStreamWriter *xml) { bool currentlyDefault = m_joyAxis->isDefault(); xml->writeStartElement(m_joyAxis->getXmlName()); xml->writeAttribute("index", QString::number(m_joyAxis->getRealJoyIndex())); if (!currentlyDefault) { if (m_joyAxis->getDeadZone() != GlobalVariables::JoyAxis::AXISDEADZONE) xml->writeTextElement("deadZone", QString::number(m_joyAxis->getDeadZone())); if (m_joyAxis->getMaxZoneValue() != GlobalVariables::JoyAxis::AXISMAXZONE) xml->writeTextElement("maxZone", QString::number(m_joyAxis->getMaxZoneValue())); } xml->writeStartElement("throttle"); switch (m_joyAxis->getThrottle()) { case -2: xml->writeCharacters("negativehalf"); break; case -1: xml->writeCharacters("negative"); break; case 0: xml->writeCharacters("normal"); break; case 1: xml->writeCharacters("positive"); break; case 2: xml->writeCharacters("positivehalf"); break; } xml->writeEndElement(); if (m_joyAxis->hasHapticTrigger()) { HapticTriggerPs5 *haptic = m_joyAxis->getHapticTrigger(); xml->writeTextElement("hapticTrigger", HapticTriggerPs5::to_string(haptic->get_mode())); } if (!currentlyDefault) { joyButtonXmlNAxis->writeConfig(xml); joyButtonXmlPAxis->writeConfig(xml); } xml->writeEndElement(); } bool JoyAxisXml::readMainConfig(QXmlStreamReader *xml) { bool found = false; if ((xml->name().toString() == "deadZone") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); qDebug() << "From xml config dead zone is: " << tempchoice; m_joyAxis->setDeadZone(tempchoice); } else if ((xml->name().toString() == "maxZone") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); qDebug() << "From xml config max zone is: " << tempchoice; m_joyAxis->setMaxZoneValue(tempchoice); } else if ((xml->name().toString() == "throttle") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); qDebug() << "From xml config throttle name is: " << temptext; if (temptext == "negativehalf") { m_joyAxis->setThrottle(static_cast(JoyAxis::NegativeHalfThrottle)); } else if (temptext == "negative") { m_joyAxis->setThrottle(static_cast(JoyAxis::NegativeThrottle)); } else if (temptext == "normal") { m_joyAxis->setThrottle(static_cast(JoyAxis::NormalThrottle)); } else if (temptext == "positive") { m_joyAxis->setThrottle(static_cast(JoyAxis::PositiveThrottle)); } else if (temptext == "positivehalf") { m_joyAxis->setThrottle(static_cast(JoyAxis::PositiveHalfThrottle)); } InputDevice *device = m_joyAxis->getParentSet()->getInputDevice(); if (!device->hasCalibrationThrottle(m_joyAxis->getIndex())) { device->setCalibrationStatus(m_joyAxis->getIndex(), static_cast(m_joyAxis->getThrottle())); } m_joyAxis->setCurrentRawValue(m_joyAxis->getCurrentThrottledDeadValue()); m_joyAxis->updateCurrentThrottledValue(m_joyAxis->calculateThrottledValue(m_joyAxis->getCurrentRawValue())); } else if ((xml->name().toString() == "hapticTrigger") && xml->isStartElement()) { found = true; m_joyAxis->setHapticTriggerMode(HapticTriggerPs5::from_string(xml->readElementText())); } return found; } bool JoyAxisXml::readButtonConfig(QXmlStreamReader *xml) { bool found = false; int index_local = xml->attributes().value("index").toString().toInt(); if (index_local == 1) { found = true; joyButtonXmlNAxis->readConfig(xml); } else if (index_local == 2) { found = true; joyButtonXmlPAxis->readConfig(xml); } return found; } AntiMicroX-antimicrox-b300273/src/xml/joyaxisxml.h000066400000000000000000000026451471077622000221300ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYAXISXML_H #define JOYAXISXML_H #include #include class JoyAxis; class JoyButtonXml; class QXmlStreamReader; class QXmlStreamWriter; class JoyAxisXml : public QObject { Q_OBJECT public: explicit JoyAxisXml(JoyAxis *axis, QObject *parent = nullptr); ~JoyAxisXml(); virtual void readConfig(QXmlStreamReader *xml); virtual void writeConfig(QXmlStreamWriter *xml); virtual bool readMainConfig(QXmlStreamReader *xml); virtual bool readButtonConfig(QXmlStreamReader *xml); private: JoyAxis *m_joyAxis; QPointer joyButtonXmlNAxis; QPointer joyButtonXmlPAxis; }; #endif // JOYAXISXML_H AntiMicroX-antimicrox-b300273/src/xml/joybuttonslotxml.cpp000066400000000000000000000376241471077622000237410ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joybuttonslotxml.h" #include "antkeymapper.h" #include "globalvariables.h" #include "joybuttonslot.h" #include #include #include #include int JoyButtonSlotXml::timeoutWrite = 5000; int JoyButtonSlotXml::timeoutRead = 5000; JoyButtonSlotXml::JoyButtonSlotXml(JoyButtonSlot *joyBtnSlot, QObject *parent) : QObject(parent) , m_joyBtnSlot(joyBtnSlot) { } void JoyButtonSlotXml::readConfig(QXmlStreamReader *xml) { // QWriteLocker tempLocker(&xmlLock); std::chrono::time_point t1, t2; t1 = std::chrono::high_resolution_clock::now(); bool result = xmlLock.tryLockForWrite(); if (!result && timeoutWrite > 0) xmlLock.tryLockForWrite(timeoutWrite); qDebug() << "START OF READ CONFIG NAME: " << xml->name().toString(); if (xml->isStartElement() && (xml->name().toString() == "slot")) { QString profile = QString(); QString tempStringData = QString(); QString extraStringData = QString(); xml->readNextStartElement(); qDebug() << "NEXT TO THE START TAG NAME: " << xml->name().toString(); // so it must be JoyMix if (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() == "slots"))) { qDebug() << "Detected mix slots"; QString slotMixString = QString(); bool firstTimePlus = true; xml->readNextStartElement(); int i = 0; while (xml->name().toString() == "slot") { qDebug() << "Found mini slot in xml file"; xml->readNextStartElement(); // skip to minislot within slots list qDebug() << "Now xml name after read next is: " << xml->name().toString(); // we don't want to add empty slot to minislots // skip again and check name of next tag if (xml->name().toString() == "slot") xml->readNextStartElement(); // if reached the end of mini slots, read next elem, that should be mode JoyMix and break loop if (xml->name().toString() == "slots") { xml->readNextStartElement(); break; } qDebug() << "And now xml name after read next is: " << xml->name().toString(); JoyButtonSlot *minislot = new JoyButtonSlot(); readEachSlot(xml, minislot, profile, tempStringData, extraStringData); i++; m_joyBtnSlot->appendMiniSlot(minislot); if (!firstTimePlus) slotMixString.append('+'); firstTimePlus = false; slotMixString.append(minislot->getSlotString()); qDebug() << "Slot mix string now is named: " << slotMixString; qDebug() << "Added " << i << " minislots to current slot from xml file"; qDebug() << "Added mini slot string and mode and code: " << minislot->getSlotString() << " and " << minislot->getSlotMode() << " and " << minislot->getSlotCode(); qDebug() << "After readEachSlot for JoyMix now should be \"slot\" again or \"mode\": " << xml->name().toString(); qDebug() << "It it start element? :" << (xml->isStartElement() ? "yes" : "no"); } i = 0; if (xml->name().toString() == "mode" && xml->readElementText() == "mix") { qDebug() << "slot text data for joy mix is: " << slotMixString; m_joyBtnSlot->setSlotMode(JoyButtonSlot::JoyMix); m_joyBtnSlot->setTextData(slotMixString); m_joyBtnSlot->setSlotCode(-1); profile = QString(); tempStringData = QString(); extraStringData = QString(); slotMixString = QString(); xml->readNextStartElement(); } } else { readEachSlot(xml, m_joyBtnSlot, profile, tempStringData, extraStringData); qDebug() << "Detected simple slot: " << m_joyBtnSlot->getSlotString(); } } xmlLock.unlock(); t2 = std::chrono::high_resolution_clock::now(); if (timeoutRead == 3000) timeoutRead = std::chrono::duration_cast(t2 - t1).count(); } void JoyButtonSlotXml::readEachSlot(QXmlStreamReader *xml, JoyButtonSlot *joyBtnSlot, QString &profile, QString &tempStringData, QString &extraStringData) { while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != "slot"))) { if ((xml->name().toString() == "code") && xml->isStartElement()) { QString temptext = xml->readElementText(); bool ok = false; int tempchoice = temptext.toInt(&ok, 0); if (ok) joyBtnSlot->setSlotCode(tempchoice); } else if ((xml->name().toString() == "profile") && xml->isStartElement()) { QString temptext = xml->readElementText(); profile = temptext; } else if ((xml->name().toString() == "text") && xml->isStartElement()) { QString temptext = xml->readElementText(); tempStringData = temptext; } else if ((xml->name().toString() == "path") && xml->isStartElement()) { QString temptext = xml->readElementText(); tempStringData = temptext; } else if ((xml->name().toString() == "arguments") && xml->isStartElement()) { QString temptext = xml->readElementText(); extraStringData = temptext; } else if ((xml->name().toString() == "mode") && xml->isStartElement()) { QString temptext = xml->readElementText(); if (temptext == "keyboard") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyKeyboard); } else if (temptext == "mousebutton") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyMouseButton); } else if (temptext == "mousemovement") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyMouseMovement); } else if (temptext == "pause") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyPause); } else if (temptext == "hold") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyHold); } else if (temptext == "cycle") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyCycle); } else if (temptext == "distance") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyDistance); } else if (temptext == "release") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyRelease); } else if (temptext == "mousespeedmod") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyMouseSpeedMod); } else if (temptext == "keypress") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyKeyPress); } else if (temptext == "delay") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyDelay); } else if (temptext == "loadprofile") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyLoadProfile); } else if (temptext == "setchange") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoySetChange); } else if (temptext == "textentry") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyTextEntry); } else if (temptext == "execute") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyExecute); } else if (temptext == "mix") { joyBtnSlot->setSlotMode(JoyButtonSlot::JoyMix); } } else { xml->skipCurrentElement(); } xml->readNextStartElement(); } setSlotData(joyBtnSlot, profile, tempStringData, extraStringData); } void JoyButtonSlotXml::setSlotData(JoyButtonSlot *joyBtnSlot, QString profile, QString tempStringData, QString extraStringData) { if (joyBtnSlot->getSlotMode() == JoyButtonSlot::JoyKeyboard) { int virtualkey = AntKeyMapper::getInstance()->returnVirtualKey(joyBtnSlot->getSlotCode()); int tempkey = joyBtnSlot->getSlotCode(); if (virtualkey) { // Mapping found a valid native keysym. joyBtnSlot->setSlotCode(virtualkey, tempkey); } else if (joyBtnSlot->getSlotCode() > QtKeyMapperBase::nativeKeyPrefix) { // Value is in the native key range. Remove prefix and use // new value as a native keysym. int temp = joyBtnSlot->getSlotCode() - QtKeyMapperBase::nativeKeyPrefix; joyBtnSlot->setSlotCode(temp); } } else if ((joyBtnSlot->getSlotMode() == JoyButtonSlot::JoyLoadProfile) && !profile.isEmpty()) { QFileInfo profileInfo(profile); if (!profileInfo.exists() || !((profileInfo.suffix() == "amgp") || (profileInfo.suffix() == "xml"))) { joyBtnSlot->setTextData(""); } else { joyBtnSlot->setTextData(profile); } } else if (joyBtnSlot->getSlotMode() == JoyButtonSlot::JoySetChange && !(joyBtnSlot->getSlotCode() >= 0) && !(joyBtnSlot->getSlotCode() < GlobalVariables::InputDevice::NUMBER_JOYSETS)) { joyBtnSlot->setSlotCode(-1); } else if ((joyBtnSlot->getSlotMode() == JoyButtonSlot::JoyTextEntry) && !tempStringData.isEmpty()) { joyBtnSlot->setTextData(tempStringData); } else if ((joyBtnSlot->getSlotMode() == JoyButtonSlot::JoyExecute) && !tempStringData.isEmpty()) { QFileInfo tempFile(tempStringData); if (tempFile.exists()) { joyBtnSlot->setTextData(tempStringData); if (!extraStringData.isEmpty()) joyBtnSlot->setExtraData(QVariant(extraStringData)); } } } void JoyButtonSlotXml::writeConfig(QXmlStreamWriter *xml) { // QReadLocker tempLocker(&xmlLock); std::chrono::time_point t1, t2; t1 = std::chrono::high_resolution_clock::now(); bool result = xmlLock.tryLockForRead(); if (!result && timeoutRead > 0) xmlLock.tryLockForRead(timeoutRead); xml->writeStartElement(m_joyBtnSlot->getXmlName()); if (m_joyBtnSlot->getSlotMode() == JoyButtonSlot::JoyMix) { qDebug() << "write JoyMix slot in xml file"; xml->writeStartElement("slots"); QListIterator iterMini(*m_joyBtnSlot->getMixSlots()); while (iterMini.hasNext()) { JoyButtonSlot *minislot = iterMini.next(); qDebug() << "write minislot: " << minislot->getSlotString(); xml->writeStartElement(m_joyBtnSlot->getXmlName()); writeEachSlot(xml, minislot); xml->writeEndElement(); } xml->writeEndElement(); xml->writeStartElement("mode"); xml->writeCharacters("mix"); xml->writeEndElement(); } else { writeEachSlot(xml, m_joyBtnSlot); } xml->writeEndElement(); xmlLock.unlock(); t2 = std::chrono::high_resolution_clock::now(); if (timeoutWrite == 3000) timeoutWrite = std::chrono::duration_cast(t2 - t1).count(); } void JoyButtonSlotXml::writeEachSlot(QXmlStreamWriter *xml, JoyButtonSlot *joyBtnSlot) { qDebug() << "slot mode for " << joyBtnSlot->getSlotString() << " is " << joyBtnSlot->getSlotMode(); if (joyBtnSlot->getSlotMode() == JoyButtonSlot::JoyKeyboard) { int basekey = AntKeyMapper::getInstance()->returnQtKey(joyBtnSlot->getSlotCode()); int qtkey = joyBtnSlot->getSlotCodeAlias(); if ((qtkey > 0) || (basekey > 0)) { // Did not add an alias to slot. If a possible Qt key value // was found, use it. if ((qtkey == 0) && (basekey > 0)) qtkey = basekey; // Found a valid abstract keysym. qDebug() << "ANT KEY: " << QString::number(qtkey, 16); xml->writeTextElement("code", QString("0x%1").arg(qtkey, 0, 16)); } else if (joyBtnSlot->getSlotCode() > 0) { // No abstraction provided for key. Add prefix to native keysym. int tempkey = joyBtnSlot->getSlotCode() | QtKeyMapperBase::nativeKeyPrefix; qDebug() << "ANT KEY: " << QString::number(tempkey, 16); xml->writeTextElement("code", QString("0x%1").arg(tempkey, 0, 16)); } } else if ((joyBtnSlot->getSlotMode() == JoyButtonSlot::JoyLoadProfile) && !joyBtnSlot->getTextData().isEmpty()) { xml->writeTextElement("profile", joyBtnSlot->getTextData()); } else if ((joyBtnSlot->getSlotMode() == JoyButtonSlot::JoyTextEntry) && !joyBtnSlot->getTextData().isEmpty()) { xml->writeTextElement("text", joyBtnSlot->getTextData()); } else if ((joyBtnSlot->getSlotMode() == JoyButtonSlot::JoyExecute) && !joyBtnSlot->getTextData().isEmpty()) { xml->writeTextElement("path", joyBtnSlot->getTextData()); if (!joyBtnSlot->getExtraData().isNull() && joyBtnSlot->getExtraData().canConvert()) { xml->writeTextElement("arguments", joyBtnSlot->getExtraData().toString()); } } else { xml->writeTextElement("code", QString::number(joyBtnSlot->getSlotCode())); } qDebug() << "write mode for " << joyBtnSlot->getSlotString(); xml->writeStartElement("mode"); switch (joyBtnSlot->getSlotMode()) { case JoyButtonSlot::JoyKeyboard: xml->writeCharacters("keyboard"); break; case JoyButtonSlot::JoyMouseButton: xml->writeCharacters("mousebutton"); break; case JoyButtonSlot::JoyMouseMovement: xml->writeCharacters("mousemovement"); break; case JoyButtonSlot::JoyPause: xml->writeCharacters("pause"); break; case JoyButtonSlot::JoyHold: xml->writeCharacters("hold"); break; case JoyButtonSlot::JoyCycle: xml->writeCharacters("cycle"); break; case JoyButtonSlot::JoyDistance: xml->writeCharacters("distance"); break; case JoyButtonSlot::JoyRelease: xml->writeCharacters("release"); break; case JoyButtonSlot::JoyMouseSpeedMod: xml->writeCharacters("mousespeedmod"); break; case JoyButtonSlot::JoyKeyPress: xml->writeCharacters("keypress"); break; case JoyButtonSlot::JoyDelay: xml->writeCharacters("delay"); break; case JoyButtonSlot::JoyLoadProfile: xml->writeCharacters("loadprofile"); break; case JoyButtonSlot::JoySetChange: xml->writeCharacters("setchange"); break; case JoyButtonSlot::JoyTextEntry: xml->writeCharacters("textentry"); break; case JoyButtonSlot::JoyExecute: xml->writeCharacters("execute"); break; case JoyButtonSlot::JoyMix: xml->writeCharacters("mix"); break; } xml->writeEndElement(); } AntiMicroX-antimicrox-b300273/src/xml/joybuttonslotxml.h000066400000000000000000000032451471077622000233760ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYBUTTONSLOTXML_H #define JOYBUTTONSLOTXML_H #include #include class QXmlStreamReader; class QXmlStreamWriter; class JoyButtonSlot; class JoyButtonSlotXml : public QObject { Q_OBJECT public: explicit JoyButtonSlotXml(JoyButtonSlot *joyBtnSlot, QObject *parent = nullptr); virtual void readConfig(QXmlStreamReader *xml); virtual void writeConfig(QXmlStreamWriter *xml); static int timeoutWrite; static int timeoutRead; private: void writeEachSlot(QXmlStreamWriter *xml, JoyButtonSlot *joyBtnSlot); void readEachSlot(QXmlStreamReader *xml, JoyButtonSlot *joyBtnSlot, QString &profile, QString &tempStringData, QString &extraStringData); void setSlotData(JoyButtonSlot *joyBtnSlot, QString profile, QString tempStringData, QString extraStringData); JoyButtonSlot *m_joyBtnSlot; QReadWriteLock xmlLock; }; #endif // JOYBUTTONSLOTXML_H AntiMicroX-antimicrox-b300273/src/xml/joybuttonxml.cpp000066400000000000000000000534071471077622000230340ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joybuttonxml.h" #include "joybuttonslotxml.h" #include "joybuttontypes/joybutton.h" #include #include #include JoyButtonXml::JoyButtonXml(JoyButton *joyButton, QObject *parent) : QObject(parent) { m_joyButton = joyButton; } bool JoyButtonXml::readButtonConfig(QXmlStreamReader *xml) { bool found = false; if ((xml->name().toString() == "toggle") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); if (temptext == "true") m_joyButton->setToggle(true); } else if ((xml->name().toString() == "turbointerval") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); m_joyButton->setTurboInterval(tempchoice); } else if ((xml->name().toString() == "turbomode") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); if (temptext == "normal") m_joyButton->setTurboMode(JoyButton::NormalTurbo); else if (temptext == "gradient") m_joyButton->setTurboMode(JoyButton::GradientTurbo); else if (temptext == "pulse") m_joyButton->setTurboMode(JoyButton::PulseTurbo); } else if ((xml->name().toString() == "useturbo") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); if (temptext == "true") m_joyButton->setUseTurbo(true); } else if ((xml->name().toString() == "mousespeedx") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); m_joyButton->setMouseSpeedX(tempchoice); } else if ((xml->name().toString() == "mousespeedy") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); m_joyButton->setMouseSpeedY(tempchoice); } else if ((xml->name().toString() == "cycleresetactive") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); if (temptext == "true") m_joyButton->setCycleResetStatus(true); } else if ((xml->name().toString() == "cycleresetinterval") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); if (tempchoice >= GlobalVariables::JoyButton::MINCYCLERESETTIME) m_joyButton->setCycleResetTime(tempchoice); } else if ((xml->name().toString() == "slots") && xml->isStartElement()) { found = true; xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != "slots"))) { if ((xml->name().toString() == "slot") && xml->isStartElement()) { JoyButtonSlot *buttonslot = new JoyButtonSlot(m_joyButton); JoyButtonSlotXml *buttonSlotXml = new JoyButtonSlotXml(buttonslot); buttonSlotXml->readConfig(xml); delete buttonSlotXml; buttonSlotXml = nullptr; if (buttonslot->isValidSlot()) { bool inserted = m_joyButton->insertAssignedSlot(buttonslot, false); if (!inserted) { if (buttonslot->getSlotMode() == JoyButtonSlot::JoyMix && buttonslot->getMixSlots() != nullptr) { qDeleteAll(*buttonslot->getMixSlots()); buttonslot->getMixSlots()->clear(); delete buttonslot->getMixSlots(); buttonslot->assignMixSlotsToNull(); } buttonslot->deleteLater(); buttonslot = nullptr; } } else { if (buttonslot->getSlotMode() == JoyButtonSlot::JoyMix && buttonslot->getMixSlots() != nullptr) { qDeleteAll(*buttonslot->getMixSlots()); buttonslot->getMixSlots()->clear(); delete buttonslot->getMixSlots(); buttonslot->assignMixSlotsToNull(); } buttonslot->deleteLater(); buttonslot = nullptr; } } else { xml->skipCurrentElement(); } xml->readNextStartElement(); } } else if ((xml->name().toString() == "setselect") && xml->isStartElement()) { if (!m_joyButton->isModifierButton()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); if ((tempchoice >= 0) && (tempchoice <= GlobalVariables::InputDevice::NUMBER_JOYSETS)) m_joyButton->setChangeSetSelection(tempchoice - 1, false); } } else if ((xml->name().toString() == "setselectcondition") && xml->isStartElement()) { if (!m_joyButton->isModifierButton()) { found = true; QString temptext = xml->readElementText(); JoyButton::SetChangeCondition tempcondition = JoyButton::SetChangeDisabled; if (temptext == "one-way") tempcondition = JoyButton::SetChangeOneWay; else if (temptext == "two-way") tempcondition = JoyButton::SetChangeTwoWay; else if (temptext == "while-held") tempcondition = JoyButton::SetChangeWhileHeld; if (tempcondition != JoyButton::SetChangeDisabled) m_joyButton->setChangeSetCondition(tempcondition, false, false); } } else if ((xml->name().toString() == "mousemode") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); if (temptext == "cursor") m_joyButton->setMouseMode(JoyButton::MouseCursor); else if (temptext == "spring") m_joyButton->setMouseMode(JoyButton::MouseSpring); } else if ((xml->name().toString() == "mouseacceleration") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); if (temptext == "linear") m_joyButton->setMouseCurve(JoyButton::LinearCurve); else if (temptext == "quadratic") m_joyButton->setMouseCurve(JoyButton::QuadraticCurve); else if (temptext == "cubic") m_joyButton->setMouseCurve(JoyButton::CubicCurve); else if (temptext == "quadratic-extreme") m_joyButton->setMouseCurve(JoyButton::QuadraticExtremeCurve); else if (temptext == "power") m_joyButton->setMouseCurve(JoyButton::PowerCurve); else if (temptext == "precision") m_joyButton->setMouseCurve(JoyButton::EnhancedPrecisionCurve); else if (temptext == "easing-quadratic") m_joyButton->setMouseCurve(JoyButton::EasingQuadraticCurve); else if (temptext == "easing-cubic") m_joyButton->setMouseCurve(JoyButton::EasingCubicCurve); } else if ((xml->name().toString() == "mousespringwidth") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); m_joyButton->setSpringWidth(tempchoice); } else if ((xml->name().toString() == "mousespringheight") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); m_joyButton->setSpringHeight(tempchoice); } else if ((xml->name().toString() == "mousesensitivity") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); double tempchoice = temptext.toDouble(); m_joyButton->setSensitivity(tempchoice); } else if ((xml->name().toString() == "actionname") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); if (!temptext.isEmpty()) m_joyButton->setActionName(temptext); } else if ((xml->name().toString() == "wheelspeedx") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); m_joyButton->setWheelSpeed(tempchoice, 'X'); } else if ((xml->name().toString() == "wheelspeedy") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); m_joyButton->setWheelSpeed(tempchoice, 'Y'); } else if ((xml->name().toString() == "relativespring") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); if (temptext == "true") m_joyButton->setSpringRelativeStatus(true); } else if ((xml->name().toString() == "easingduration") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); double tempchoice = temptext.toDouble(); m_joyButton->setEasingDuration(tempchoice); } else if ((xml->name().toString() == "extraacceleration") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); if (temptext == "true") m_joyButton->setExtraAccelerationStatus(true); } else if ((xml->name().toString() == "accelerationmultiplier") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); double tempchoice = temptext.toDouble(); m_joyButton->setExtraAccelerationMultiplier(tempchoice); } else if ((xml->name().toString() == "startaccelmultiplier") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); double tempchoice = temptext.toDouble(); m_joyButton->setStartAccelMultiplier(tempchoice); } else if ((xml->name().toString() == "minaccelthreshold") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); double tempchoice = temptext.toDouble(); m_joyButton->setMinAccelThreshold(tempchoice); } else if ((xml->name().toString() == "maxaccelthreshold") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); double tempchoice = temptext.toDouble(); m_joyButton->setMaxAccelThreshold(tempchoice); } else if ((xml->name().toString() == "accelextraduration") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); double tempchoice = temptext.toDouble(); m_joyButton->setAccelExtraDuration(tempchoice); } else if ((xml->name().toString() == "extraaccelerationcurve") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); JoyButton::JoyExtraAccelerationCurve tempcurve = JoyButton::DEFAULTEXTRAACCELCURVE; if (temptext == "linear") tempcurve = JoyButton::LinearAccelCurve; else if (temptext == "easeoutsine") tempcurve = JoyButton::EaseOutSineCurve; else if (temptext == "easeoutquad") tempcurve = JoyButton::EaseOutQuadAccelCurve; else if (temptext == "easeoutcubic") tempcurve = JoyButton::EaseOutCubicAccelCurve; m_joyButton->setExtraAccelerationCurve(tempcurve); } else if ((xml->name().toString() == "springreleaseradius") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); if (!m_joyButton->isRelativeSpring()) m_joyButton->setSpringDeadCircleMultiplier(tempchoice); } return found; } void JoyButtonXml::readConfig(QXmlStreamReader *xml) { if (xml->isStartElement() && (xml->name().toString() == m_joyButton->getXmlName())) { xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != m_joyButton->getXmlName()))) { bool found = readButtonConfig(xml); if (!found) xml->skipCurrentElement(); else m_joyButton->buildActiveZoneSummaryString(); xml->readNextStartElement(); } } } void JoyButtonXml::writeConfig(QXmlStreamWriter *xml) { if (!m_joyButton->isDefault()) { xml->writeStartElement(m_joyButton->getXmlName()); xml->writeAttribute("index", QString::number(m_joyButton->getRealJoyNumber())); if (m_joyButton->getToggleState() != GlobalVariables::JoyButton::DEFAULTTOGGLE) xml->writeTextElement("toggle", m_joyButton->getToggleState() ? "true" : "false"); if (m_joyButton->getTurboInterval() != GlobalVariables::JoyButton::DEFAULTTURBOINTERVAL) xml->writeTextElement("turbointerval", QString::number(m_joyButton->getTurboInterval())); if ((m_joyButton->getTurboMode() != JoyButton::DEFAULTTURBOMODE) && (m_joyButton->getTurboMode() == JoyButton::GradientTurbo)) xml->writeTextElement("turbomode", "gradient"); else if ((m_joyButton->getTurboMode() != JoyButton::DEFAULTTURBOMODE) && (m_joyButton->getTurboMode() == JoyButton::PulseTurbo)) xml->writeTextElement("turbomode", "pulse"); if (m_joyButton->isUsingTurbo() != GlobalVariables::JoyButton::DEFAULTUSETURBO) xml->writeTextElement("useturbo", m_joyButton->isUsingTurbo() ? "true" : "false"); if (m_joyButton->getMouseSpeedX() != GlobalVariables::JoyButton::DEFAULTMOUSESPEEDX) xml->writeTextElement("mousespeedx", QString::number(m_joyButton->getMouseSpeedX())); if (m_joyButton->getMouseSpeedY() != GlobalVariables::JoyButton::DEFAULTMOUSESPEEDY) xml->writeTextElement("mousespeedy", QString::number(m_joyButton->getMouseSpeedY())); if ((m_joyButton->getMouseMode() != JoyButton::DEFAULTMOUSEMODE) && (m_joyButton->getMouseMode() == JoyButton::MouseCursor)) { xml->writeTextElement("mousemode", "cursor"); } else if ((m_joyButton->getMouseMode() != JoyButton::DEFAULTMOUSEMODE) && (m_joyButton->getMouseMode() == JoyButton::MouseSpring)) { xml->writeTextElement("mousemode", "spring"); xml->writeTextElement("mousespringwidth", QString::number(m_joyButton->getSpringWidth())); xml->writeTextElement("mousespringheight", QString::number(m_joyButton->getSpringHeight())); } if (m_joyButton->getMouseCurve() != m_joyButton->getDefaultMouseCurve()) { switch (m_joyButton->getMouseCurve()) { case JoyButton::LinearCurve: xml->writeTextElement("mouseacceleration", "linear"); break; case JoyButton::QuadraticCurve: xml->writeTextElement("mouseacceleration", "quadratic"); break; case JoyButton::CubicCurve: xml->writeTextElement("mouseacceleration", "cubic"); break; case JoyButton::QuadraticExtremeCurve: xml->writeTextElement("mouseacceleration", "quadratic-extreme"); break; case JoyButton::PowerCurve: xml->writeTextElement("mouseacceleration", "power"); xml->writeTextElement("mousesensitivity", QString::number(m_joyButton->getSensitivity())); break; case JoyButton::EnhancedPrecisionCurve: xml->writeTextElement("mouseacceleration", "precision"); break; case JoyButton::EasingQuadraticCurve: xml->writeTextElement("mouseacceleration", "easing-quadratic"); break; case JoyButton::EasingCubicCurve: xml->writeTextElement("mouseacceleration", "easing-cubic"); break; } } if (m_joyButton->getWheelSpeedX() != GlobalVariables::JoyButton::DEFAULTWHEELX) xml->writeTextElement("wheelspeedx", QString::number(m_joyButton->getWheelSpeedX())); if (m_joyButton->getWheelSpeedY() != GlobalVariables::JoyButton::DEFAULTWHEELY) xml->writeTextElement("wheelspeedy", QString::number(m_joyButton->getWheelSpeedY())); if (!m_joyButton->isModifierButton()) { if (m_joyButton->getChangeSetCondition() != JoyButton::SetChangeDisabled) { xml->writeTextElement("setselect", QString::number(m_joyButton->getSetSelection() + 1)); QString temptext = QString(); switch (m_joyButton->getChangeSetCondition()) { case JoyButton::SetChangeOneWay: temptext = "one-way"; break; case JoyButton::SetChangeTwoWay: temptext = "two-way"; break; case JoyButton::SetChangeWhileHeld: temptext = "while-held"; break; default: break; } xml->writeTextElement("setselectcondition", temptext); } } if (!m_joyButton->getActionName().isEmpty()) xml->writeTextElement("actionname", m_joyButton->getActionName()); if (m_joyButton->isCycleResetActive()) xml->writeTextElement("cycleresetactive", "true"); if (m_joyButton->getCycleResetTime() >= GlobalVariables::JoyButton::MINCYCLERESETTIME) xml->writeTextElement("cycleresetinterval", QString::number(m_joyButton->getCycleResetTime())); if (m_joyButton->isRelativeSpring()) xml->writeTextElement("relativespring", "true"); if (!qFuzzyCompare(m_joyButton->getEasingDuration(), GlobalVariables::JoyButton::DEFAULTEASINGDURATION)) xml->writeTextElement("easingduration", QString::number(m_joyButton->getEasingDuration())); if (m_joyButton->isExtraAccelerationEnabled()) xml->writeTextElement("extraacceleration", "true"); if (!qFuzzyCompare(m_joyButton->getExtraAccelerationMultiplier(), GlobalVariables::JoyButton::DEFAULTEXTRACCELVALUE)) xml->writeTextElement("accelerationmultiplier", QString::number(m_joyButton->getExtraAccelerationMultiplier())); if (!qFuzzyCompare(m_joyButton->getStartAccelMultiplier(), GlobalVariables::JoyButton::DEFAULTSTARTACCELMULTIPLIER)) xml->writeTextElement("startaccelmultiplier", QString::number(m_joyButton->getStartAccelMultiplier())); if (!qFuzzyCompare(m_joyButton->getMinAccelThreshold(), GlobalVariables::JoyButton::DEFAULTMINACCELTHRESHOLD)) xml->writeTextElement("minaccelthreshold", QString::number(m_joyButton->getMinAccelThreshold())); if (!qFuzzyCompare(m_joyButton->getMaxAccelThreshold(), GlobalVariables::JoyButton::DEFAULTMAXACCELTHRESHOLD)) xml->writeTextElement("maxaccelthreshold", QString::number(m_joyButton->getMaxAccelThreshold())); if (!qFuzzyCompare(m_joyButton->getAccelExtraDuration(), GlobalVariables::JoyButton::DEFAULTACCELEASINGDURATION)) xml->writeTextElement("accelextraduration", QString::number(m_joyButton->getAccelExtraDuration())); if (m_joyButton->getSpringDeadCircleMultiplier() != GlobalVariables::JoyButton::DEFAULTSPRINGRELEASERADIUS) xml->writeTextElement("springreleaseradius", QString::number(m_joyButton->getSpringDeadCircleMultiplier())); if (m_joyButton->getExtraAccelerationCurve() != JoyButton::DEFAULTEXTRAACCELCURVE) { QString temp = QString(); switch (m_joyButton->getExtraAccelerationCurve()) { case JoyButton::LinearAccelCurve: temp = "linear"; break; case JoyButton::EaseOutSineCurve: temp = "easeoutsine"; break; case JoyButton::EaseOutQuadAccelCurve: temp = "easeoutquad"; break; case JoyButton::EaseOutCubicAccelCurve: temp = "easeoutcubic"; break; } if (!temp.isEmpty()) xml->writeTextElement("extraaccelerationcurve", temp); } // Write information about assigned slots. if (!m_joyButton->getAssignedSlots()->isEmpty()) { xml->writeStartElement("slots"); QListIterator iter(*m_joyButton->getAssignedSlots()); while (iter.hasNext()) { JoyButtonSlot *buttonslot = iter.next(); JoyButtonSlotXml *buttonslotxml = new JoyButtonSlotXml(buttonslot); buttonslotxml->writeConfig(xml); delete buttonslotxml; buttonslotxml = nullptr; } xml->writeEndElement(); } xml->writeEndElement(); } } AntiMicroX-antimicrox-b300273/src/xml/joybuttonxml.h000066400000000000000000000023541471077622000224740ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYBUTTONXML_H #define JOYBUTTONXML_H #include class JoyButton; class QXmlStreamReader; class QXmlStreamWriter; class JoyButtonXml : public QObject { Q_OBJECT public: explicit JoyButtonXml(JoyButton *joyButton, QObject *parent = nullptr); virtual bool readButtonConfig(QXmlStreamReader *xml); virtual void readConfig(QXmlStreamReader *xml); virtual void writeConfig(QXmlStreamWriter *xml); private: JoyButton *m_joyButton; }; #endif // JOYBUTTONXML_H AntiMicroX-antimicrox-b300273/src/xml/joydpadxml.cpp000066400000000000000000000070411471077622000224220ustar00rootroot00000000000000 #include "joydpadxml.h" #include "globalvariables.h" #include "gamecontroller/gamecontrollerdpad.h" #include "joydpad.h" #include "vdpad.h" #include "xml/joybuttonxml.h" #include #include #include #include #include template JoyDPadXml::JoyDPadXml(T *joydpad, QObject *parent) : QObject(parent) { m_joydpad = joydpad; } template void JoyDPadXml::readConfig(QXmlStreamReader *xml) { if (xml->isStartElement() && (xml->name().toString() == m_joydpad->getXmlName())) { xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != m_joydpad->getXmlName()))) { bool found = readMainConfig(xml); if (!found) { xml->skipCurrentElement(); } xml->readNextStartElement(); } } } template void JoyDPadXml::writeConfig(QXmlStreamWriter *xml) { if (!m_joydpad->isDefault()) { xml->writeStartElement(m_joydpad->getXmlName()); xml->writeAttribute("index", QString::number(m_joydpad->getRealJoyNumber())); if (m_joydpad->getJoyMode() == JoyDPad::EightWayMode) { xml->writeTextElement("mode", "eight-way"); } else if (m_joydpad->getJoyMode() == JoyDPad::FourWayCardinal) { xml->writeTextElement("mode", "four-way"); } else if (m_joydpad->getJoyMode() == JoyDPad::FourWayDiagonal) { xml->writeTextElement("mode", "diagonal"); } if (m_joydpad->getDPadDelay() > GlobalVariables::JoyDPad::DEFAULTDPADDELAY) { xml->writeTextElement("dpadDelay", QString::number(m_joydpad->getDPadDelay())); } QHashIterator iter(*m_joydpad->getJoyButtons()); while (iter.hasNext()) { JoyDPadButton *button = iter.next().value(); JoyButtonXml *joyBtnXml = new JoyButtonXml(button); joyBtnXml->writeConfig(xml); } xml->writeEndElement(); } } template bool JoyDPadXml::readMainConfig(QXmlStreamReader *xml) { bool found = false; if ((xml->name().toString() == "dpadbutton") && xml->isStartElement()) { found = true; int index_local = xml->attributes().value("index").toString().toInt(); JoyDPadButton *button = m_joydpad->getJoyButton(index_local); if (button != nullptr) { JoyButtonXml *joyBtnXml = new JoyButtonXml(button); joyBtnXml->readConfig(xml); } else { xml->skipCurrentElement(); } } else if ((xml->name().toString() == "mode") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); if (temptext == "eight-way") { m_joydpad->setJoyMode(JoyDPad::EightWayMode); } else if (temptext == "four-way") { m_joydpad->setJoyMode(JoyDPad::FourWayCardinal); } else if (temptext == "diagonal") { m_joydpad->setJoyMode(JoyDPad::FourWayDiagonal); } } else if ((xml->name().toString() == "dpadDelay") && xml->isStartElement()) { found = true; QString temptext = xml->readElementText(); int tempchoice = temptext.toInt(); m_joydpad->setDPadDelay(tempchoice); } return found; } template class JoyDPadXml; template class JoyDPadXml; template class JoyDPadXml; AntiMicroX-antimicrox-b300273/src/xml/joydpadxml.h000066400000000000000000000023211471077622000220630ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef JOYDPADXML_H #define JOYDPADXML_H #include class QXmlStreamReader; class QXmlStreamWriter; template class JoyDPadXml : public QObject { public: explicit JoyDPadXml(T *joydpad, QObject *parent = nullptr); void readConfig(QXmlStreamReader *xml); // JoyDPadXml class void writeConfig(QXmlStreamWriter *xml); // JoyDPadXml class bool readMainConfig(QXmlStreamReader *xml); private: T *m_joydpad; }; #endif // JOYDPADXML_H AntiMicroX-antimicrox-b300273/src/xml/setjoystickxml.cpp000066400000000000000000000171341471077622000233470ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "setjoystickxml.h" #include "xml/joyaxisxml.h" #include "xml/joybuttonxml.h" #include "xml/joydpadxml.h" #include #include #include "joyaxis.h" #include "joybuttontypes/joybutton.h" #include "joycontrolstick.h" #include "joydpad.h" #include "joysensor.h" #include "vdpad.h" #include "setjoystick.h" #include #include #include #include #include SetJoystickXml::SetJoystickXml(SetJoystick *setJoystick, QObject *parent) : QObject(parent) , m_setJoystick(setJoystick) { } /** * @brief Deserializes the given XML stream into a SetJoystick object * @param[in] xml The XML stream to read from */ void SetJoystickXml::readConfig(QXmlStreamReader *xml) { if (xml->isStartElement() && (xml->name().toString() == "set")) { xml->readNextStartElement(); while (!xml->atEnd() && (!xml->isEndElement() && (xml->name().toString() != "set"))) { if ((xml->name().toString() == "button") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); JoyButton *button = m_setJoystick->getJoyButton(index - 1); joyButtonXml = new JoyButtonXml(button); if (button != nullptr) joyButtonXml->readConfig(xml); else xml->skipCurrentElement(); } else if ((xml->name().toString() == "axis") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); JoyAxis *axis = m_setJoystick->getJoyAxis(index - 1); joyAxisXml = new JoyAxisXml(axis); if (axis != nullptr) joyAxisXml->readConfig(xml); else xml->skipCurrentElement(); } else if ((xml->name().toString() == "dpad") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); JoyDPad *dpad = m_setJoystick->getJoyDPad(index - 1); JoyDPadXml *joydpadXml = new JoyDPadXml(dpad); if (dpad != nullptr) joydpadXml->readConfig(xml); else xml->skipCurrentElement(); } else if ((xml->name().toString() == "stick") && xml->isStartElement()) { int stickIndex = xml->attributes().value("index").toString().toInt(); if (stickIndex > 0) { stickIndex -= 1; JoyControlStick *stick = m_setJoystick->getJoyStick(stickIndex); if (stick != nullptr) stick->readConfig(xml); else xml->skipCurrentElement(); } else { xml->skipCurrentElement(); } } else if ((xml->name().toString() == "sensor") && xml->isStartElement()) { int type = xml->attributes().value("type").toString().toInt(); JoySensor *sensor = m_setJoystick->getSensor(static_cast(type)); if (sensor != nullptr) sensor->readConfig(xml); else xml->skipCurrentElement(); } else if ((xml->name().toString() == "vdpad") && xml->isStartElement()) { int index = xml->attributes().value("index").toString().toInt(); VDPad *vdpad = m_setJoystick->getVDPad(index - 1); JoyDPadXml *joydpadXml = new JoyDPadXml(vdpad); if (vdpad != nullptr) joydpadXml->readConfig(xml); else xml->skipCurrentElement(); } else if ((xml->name().toString() == "name") && xml->isStartElement()) { QString temptext = xml->readElementText(); if (!temptext.isEmpty()) m_setJoystick->setName(temptext); } else { xml->skipCurrentElement(); // If none of the above, skip the element } xml->readNextStartElement(); } } } /** * @brief Serializes a SetJoystick object into the the given XML stream * @param[in,out] xml The XML stream to write to */ void SetJoystickXml::writeConfig(QXmlStreamWriter *xml) { if (!m_setJoystick->isSetEmpty()) { xml->writeStartElement("set"); xml->writeAttribute("index", QString::number(m_setJoystick->getIndex() + 1)); if (!m_setJoystick->getName().isEmpty()) xml->writeTextElement("name", m_setJoystick->getName()); QList sticksList = m_setJoystick->getSticks().values(); QListIterator i(sticksList); while (i.hasNext()) i.next()->writeConfig(xml); auto sensors = m_setJoystick->getSensors(); for (const auto &sensor : sensors) sensor->writeConfig(xml); QList vdpadsList = m_setJoystick->getVdpads().values(); QListIterator vdpad(vdpadsList); while (vdpad.hasNext()) { JoyDPadXml *joydpadXml = new JoyDPadXml(vdpad.next()); joydpadXml->writeConfig(xml); delete joydpadXml; joydpadXml = nullptr; } QList axesList = m_setJoystick->getAxes()->values(); QListIterator axis(axesList); while (axis.hasNext()) { JoyAxis *axisCur = axis.next(); JoyAxisXml *joyAxisXml = new JoyAxisXml(axisCur); if (!axisCur->isPartControlStick() && axisCur->hasControlOfButtons()) { joyAxisXml->writeConfig(xml); } delete joyAxisXml; joyAxisXml = nullptr; } QList dpadsList = m_setJoystick->getHats().values(); QListIterator dpad(dpadsList); while (dpad.hasNext()) { JoyDPadXml *joydpadXml = new JoyDPadXml(dpad.next()); joydpadXml->writeConfig(xml); delete joydpadXml; joydpadXml = nullptr; } QList buttonsList = m_setJoystick->getButtons().values(); QListIterator button(buttonsList); while (button.hasNext()) { JoyButton *buttonCurr = button.next(); if ((buttonCurr != nullptr) && !buttonCurr->isPartVDPad()) { JoyButtonXml *joyButtonXml = new JoyButtonXml(buttonCurr); joyButtonXml->writeConfig(xml); delete joyButtonXml; joyButtonXml = nullptr; } } xml->writeEndElement(); } } AntiMicroX-antimicrox-b300273/src/xml/setjoystickxml.h000066400000000000000000000030621471077622000230070ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SETJOYSTICKXML_H #define SETJOYSTICKXML_H #include class SetJoystick; class JoyAxisXml; class JoyButtonXml; class QXmlStreamReader; class QXmlStreamWriter; /** * @brief SetJoystick XML serialization/deserialization helper class * Reads data from the supplied SetJoystick object and writes it to XML or * reads data from an QXmlStreamReader and writes it to the SetJoystick object. */ class SetJoystickXml : public QObject { Q_OBJECT public: explicit SetJoystickXml(SetJoystick *setJoystick, QObject *parent = nullptr); virtual void readConfig(QXmlStreamReader *xml); virtual void writeConfig(QXmlStreamWriter *xml); private: SetJoystick *m_setJoystick; // JoyDPadXml* joydpadXml; JoyAxisXml *joyAxisXml; JoyButtonXml *joyButtonXml; }; #endif // SETJOYSTICKXML_H AntiMicroX-antimicrox-b300273/src/xmlconfigmigration.cpp000066400000000000000000000126671471077622000233610ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "xmlconfigmigration.h" #include "antkeymapper.h" #include "common.h" #include "event.h" #include "eventhandlerfactory.h" #include #include #include XMLConfigMigration::XMLConfigMigration(QXmlStreamReader *reader, QObject *parent) : QObject(parent) { this->reader = reader; if (reader->device() && reader->device()->isOpen()) { this->fileVersion = reader->attributes().value("configversion").toString().toInt(); } else { this->fileVersion = 0; } } bool XMLConfigMigration::requiresMigration() { bool toMigrate = false; if ((fileVersion >= 2) && (fileVersion <= PadderCommon::LATESTCONFIGMIGRATIONVERSION)) { toMigrate = true; } return toMigrate; } QString XMLConfigMigration::migrate() { QString tempXmlString = QString(); if (requiresMigration()) { QString initialData = readConfigToString(); reader->clear(); reader->addData(initialData); if ((fileVersion >= 2) && (fileVersion <= 5)) { tempXmlString = version0006Migration(); fileVersion = PadderCommon::LATESTCONFIGFILEVERSION; } } return tempXmlString; } QString XMLConfigMigration::readConfigToString() { QString tempXmlString = QString(); QXmlStreamWriter writer(&tempXmlString); writer.setAutoFormatting(true); while (!reader->atEnd()) { writer.writeCurrentToken(*reader); reader->readNext(); } return tempXmlString; } QString XMLConfigMigration::version0006Migration() { QString tempXmlString = QString(); QXmlStreamWriter writer(&tempXmlString); writer.setAutoFormatting(true); reader->readNextStartElement(); reader->readNextStartElement(); writer.writeStartDocument(); writer.writeStartElement("joystick"); writer.writeAttribute("configversion", QString::number(6)); writer.writeAttribute("appversion", PadderCommon::programVersion); while (!reader->atEnd()) { if ((reader->name() == u"slot") && reader->isStartElement()) { int slotcode = 0; QString slotmode = QString(); writer.writeCurrentToken(*reader); reader->readNext(); // Grab current slot code and slot mode while (!reader->atEnd() && (!reader->isEndElement() && (reader->name() != u"slot"))) { if ((reader->name() == u"code") && reader->isStartElement()) { QString tempcode = reader->readElementText(); slotcode = tempcode.toInt(); } else if ((reader->name() == u"mode") && reader->isStartElement()) { slotmode = reader->readElementText(); } else { writer.writeCurrentToken(*reader); } reader->readNext(); } // Reformat slot code if associated with the keyboard if (slotcode && !slotmode.isEmpty()) { if (slotmode == "keyboard") { int tempcode = slotcode; #ifdef Q_OS_WIN slotcode = AntKeyMapper::getInstance()->returnQtKey(slotcode); #else BaseEventHandler *handler = EventHandlerFactory::getInstance()->handler(); if (handler->getIdentifier() == "xtest") { slotcode = AntKeyMapper::getInstance()->returnQtKey(X11KeyCodeToX11KeySym(slotcode)); } else { slotcode = 0; tempcode = 0; } #endif if (slotcode > 0) { writer.writeTextElement("code", QString("0x%1").arg(slotcode, 0, 16)); } else if (tempcode > 0) { writer.writeTextElement("code", QString("0x%1").arg(tempcode | QtKeyMapperBase::nativeKeyPrefix, 0, 16)); } } else { writer.writeTextElement("code", QString::number(slotcode)); } writer.writeTextElement("mode", slotmode); } writer.writeCurrentToken(*reader); } else { writer.writeCurrentToken(*reader); } reader->readNext(); } return tempXmlString; } const QXmlStreamReader *XMLConfigMigration::getReader() { return reader; } int XMLConfigMigration::getFileVersion() const { return fileVersion; } AntiMicroX-antimicrox-b300273/src/xmlconfigmigration.h000066400000000000000000000025371471077622000230210ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef XMLCONFIGMIGRATION_H #define XMLCONFIGMIGRATION_H #include class QXmlStreamReader; class XMLConfigMigration : public QObject { Q_OBJECT public: explicit XMLConfigMigration(QXmlStreamReader *reader, QObject *parent = nullptr); bool requiresMigration(); QString migrate(); const QXmlStreamReader *getReader(); int getFileVersion() const; private: QString readConfigToString(); QString version0006Migration(); QXmlStreamReader *reader; int fileVersion; }; #endif // XMLCONFIGMIGRATION_H AntiMicroX-antimicrox-b300273/src/xmlconfigreader.cpp000066400000000000000000000134411471077622000226210ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "xmlconfigreader.h" #include "common.h" #include "globalvariables.h" #include "inputdevice.h" #include "joystick.h" #include "xml/inputdevicexml.h" #include "xmlconfigmigration.h" #include "xmlconfigwriter.h" #include "common.h" #include "gamecontroller/gamecontroller.h" #include #include #include #include #include /** * @brief Main XML config writer class */ XMLConfigReader::XMLConfigReader(QObject *parent) : QObject(parent) { xml = new QXmlStreamReader(); configFile = nullptr; m_joystick = nullptr; initDeviceTypes(); } XMLConfigReader::~XMLConfigReader() { if (configFile != nullptr) { if (configFile->isOpen()) configFile->close(); delete configFile; configFile = nullptr; } if (xml != nullptr) { delete xml; xml = nullptr; } } void XMLConfigReader::setJoystick(InputDevice *joystick) { m_joystick = joystick; } /** * @brief Sets the filename of the to be read XML file */ void XMLConfigReader::setFileName(QString filename) { QFile *temp = new QFile(filename); if (temp->exists()) { configFile = temp; } else { delete temp; temp = nullptr; } } /** * @brief Read input device config from the current XML file into the InputDevice object * @param[in,out] joystick InputDevice into which the config is read */ void XMLConfigReader::configJoystick(InputDevice *joystick) { m_joystick = joystick; read(); } bool XMLConfigReader::read() { bool error = false; if ((configFile != nullptr) && configFile->exists() && (m_joystick != nullptr)) { xml->clear(); if (!configFile->isOpen()) { if (configFile->open(QFile::ReadOnly | QFile::Text)) xml->setDevice(configFile); else WARN() << "Could not open file: " << configFile->fileName(); } xml->readNextStartElement(); if (!deviceTypes.contains(xml->name().toString())) { xml->raiseError("Root node is not a joystick or controller"); } else if (xml->name().toString() == GlobalVariables::Joystick::xmlName) { XMLConfigMigration migration(xml); if (migration.requiresMigration()) { QString migrationString = migration.migrate(); if (migrationString.length() > 0) { xml->clear(); // Remove QFile from reader and clear state xml->addData(migrationString); // Add converted XML string to reader xml->readNextStartElement(); // Skip joystick root node configFile->close(); // Close current config file configFile->open(QFile::WriteOnly | QFile::Text); // Write converted XML to file if (configFile->isOpen()) { configFile->write(migrationString.toLocal8Bit()); configFile->close(); } else { xml->raiseError(tr("Could not write updated profile XML to file %1.").arg(configFile->fileName())); } } } } while (!xml->atEnd()) { if (xml->isStartElement() && deviceTypes.contains(xml->name().toString())) { InputDeviceXml *joystick_xml = new InputDeviceXml(m_joystick); joystick_xml->readConfig(xml); joystick_xml->deleteLater(); } else { // If none of the above, skip the element xml->skipCurrentElement(); } xml->readNextStartElement(); } if (configFile->isOpen()) configFile->close(); if (xml->hasError() && (xml->error() != QXmlStreamReader::PrematureEndOfDocumentError)) { error = true; } else if (xml->hasError() && (xml->error() == QXmlStreamReader::PrematureEndOfDocumentError)) { xml->clear(); } } return error; } const QString XMLConfigReader::getErrorString() { QString temp = QString(); if (xml->hasError()) temp = xml->errorString(); return temp; } bool XMLConfigReader::hasError() { return xml->hasError(); } void XMLConfigReader::initDeviceTypes() { deviceTypes.clear(); deviceTypes.append(GlobalVariables::Joystick::xmlName); deviceTypes.append(GlobalVariables::GameController::xmlName); } const QXmlStreamReader *XMLConfigReader::getXml() { return xml; } QString const &XMLConfigReader::getFileName() { return fileName; } const QFile *XMLConfigReader::getConfigFile() { return configFile; } const InputDevice *XMLConfigReader::getJoystick() { return m_joystick; } QStringList const &XMLConfigReader::getDeviceTypes() { return deviceTypes; } AntiMicroX-antimicrox-b300273/src/xmlconfigreader.h000066400000000000000000000034261471077622000222700ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef XMLCONFIGREADER_H #define XMLCONFIGREADER_H #include #include class InputDevice; class QXmlStreamReader; class InputDeviceXml; class QFile; /** * @brief Main XML config reader class */ class XMLConfigReader : public QObject { Q_OBJECT public: explicit XMLConfigReader(QObject *parent = nullptr); ~XMLConfigReader(); void setJoystick(InputDevice *joystick); void setFileName(QString filename); const QString getErrorString(); bool hasError(); bool read(); const QXmlStreamReader *getXml(); QString const &getFileName(); const QFile *getConfigFile(); const InputDevice *getJoystick(); QStringList const &getDeviceTypes(); protected: void initDeviceTypes(); public slots: void configJoystick(InputDevice *joystick); private: QXmlStreamReader *xml; QString fileName; QFile *configFile; InputDevice *m_joystick; QStringList deviceTypes; }; #endif // XMLCONFIGREADER_H AntiMicroX-antimicrox-b300273/src/xmlconfigwriter.cpp000066400000000000000000000055071471077622000226770ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "xmlconfigwriter.h" #include "common.h" #include "inputdevice.h" #include "xml/inputdevicexml.h" #include #include #include #include XMLConfigWriter::XMLConfigWriter(QObject *parent) : QObject(parent) { xml = new QXmlStreamWriter(); xml->setAutoFormatting(true); configFile = nullptr; m_joystick = nullptr; m_joystickXml = nullptr; writerError = false; } XMLConfigWriter::~XMLConfigWriter() { if (configFile != nullptr) { if (configFile->isOpen()) configFile->close(); delete configFile; configFile = nullptr; } if (xml != nullptr) { delete xml; xml = nullptr; } } /** * @brief Write input device config from the current object into XML file * @param[in] joystickXml InputDeviceXml which gets serialized */ void XMLConfigWriter::write(InputDeviceXml *joystickXml) { writerError = false; if (!configFile->isOpen()) { configFile->open(QFile::WriteOnly | QFile::Text); xml->setDevice(configFile); } else { writerError = true; writerErrorString = tr("Could not write to profile at %1.").arg(configFile->fileName()); } if (!writerError) { xml->writeStartDocument(); joystickXml->writeConfig(xml); xml->writeEndDocument(); } if (configFile->isOpen()) configFile->close(); } /** * @brief Sets the filename of the to be written XML file */ void XMLConfigWriter::setFileName(QString filename) { QFile *temp = new QFile(filename); fileName = filename; configFile = temp; } bool XMLConfigWriter::hasError() { return writerError; } const QString XMLConfigWriter::getErrorString() { return writerErrorString; } const QXmlStreamWriter *XMLConfigWriter::getXml() { return xml; } QString const &XMLConfigWriter::getFileName() { return fileName; } const QFile *XMLConfigWriter::getConfigFile() { return configFile; } const InputDevice *XMLConfigWriter::getJoystick() { return m_joystick; } AntiMicroX-antimicrox-b300273/src/xmlconfigwriter.h000066400000000000000000000031671471077622000223440ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef XMLCONFIGWRITER_H #define XMLCONFIGWRITER_H #include class InputDevice; class QXmlStreamWriter; class InputDeviceXml; class QFile; class XMLConfigWriter : public QObject { Q_OBJECT public: explicit XMLConfigWriter(QObject *parent = nullptr); ~XMLConfigWriter(); void setFileName(QString filename); bool hasError(); const QString getErrorString(); const QXmlStreamWriter *getXml(); QString const &getFileName(); const QFile *getConfigFile(); const InputDevice *getJoystick(); public slots: void write(InputDeviceXml *joystickXml); private: QXmlStreamWriter *xml; QString fileName; QFile *configFile; InputDevice *m_joystick; InputDeviceXml *m_joystickXml; bool writerError; QString writerErrorString; }; #endif // XMLCONFIGWRITER_H AntiMicroX-antimicrox-b300273/tests/000077500000000000000000000000001471077622000173145ustar00rootroot00000000000000AntiMicroX-antimicrox-b300273/tests/CMakeLists.txt000066400000000000000000000013111471077622000220500ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8.11) project(aboutdialogClass) # Tell CMake to run moc when necessary: set(CMAKE_AUTOMOC ON) # As moc files are generated in the binary dir, tell CMake # to always look for includes there: set(CMAKE_INCLUDE_CURRENT_DIR ON) find_package(Qt5Test REQUIRED) set(GUIS_SRCS testaboutdialog.cpp testaddeditautoprofiledialog.cpp testadvancebuttondialog.cpp testcalibration.cpp testjoycontrolstickeditdialog.cpp testbuttoneditdialog.cpp testquicksetdialog.cpp testqkeydisplaydialog.cpp ) add_executable(GuiTests ${GUIS_SRCS}) #target_link_libraries( GuiTests antilib Qt5::Test ) ADD_TEST(NAME GuiTests COMMAND GuiTests) AntiMicroX-antimicrox-b300273/tests/testaboutdialog.cpp000066400000000000000000000054701471077622000232200ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "aboutdialog.h" #include #include #include #include class TestAboutDialog: public QObject { Q_OBJECT public: TestAboutDialog(QObject* parent = 0); private slots: void testVersion(); void infoTextBrowserEmpty(); void changelogPlainEmpty(); void textBrowserDevsEmpty(); void licenseInfoEmpty(); void creditsInfoEmpty(); private: AboutDialog aboutDialog; }; TestAboutDialog::TestAboutDialog(QObject* parent) : QObject(parent), aboutDialog() { QTestEventLoop::instance().enterLoop(1); } void TestAboutDialog::infoTextBrowserEmpty() { QTextBrowser* infoTextBrowser = aboutDialog.findChild("infoTextBrowser"); QVERIFY2(!infoTextBrowser->toPlainText().isEmpty(), "infoTextBrowser is empty"); } void TestAboutDialog::changelogPlainEmpty() { QPlainTextEdit* changelogText = aboutDialog.findChild("changelogText"); QVERIFY2(!changelogText->toPlainText().isEmpty(), "changelogText is empty"); } void TestAboutDialog::textBrowserDevsEmpty() { QPlainTextEdit* developersInfo = aboutDialog.findChild("plainTextEdit"); QVERIFY2(!developersInfo->toPlainText().isEmpty(), "plainTextEdit for info about developers is empty"); } void TestAboutDialog::licenseInfoEmpty() { QTextBrowser* licenseInfo = aboutDialog.findChild("textBrowser_2"); QVERIFY2(!licenseInfo->toPlainText().isEmpty(), "textBrowser_2 about license information is empty"); } void TestAboutDialog::creditsInfoEmpty() { QTextBrowser* creditsInfo = aboutDialog.findChild("textBrowser"); QVERIFY2(!creditsInfo->toPlainText().isEmpty(), "textBrowser about credits is empty"); } void TestAboutDialog::testVersion() { QLabel* versionLabel = aboutDialog.findChild("versionLabel"); QCOMPARE(versionLabel->text(), QString("2.25")); } QTEST_MAIN(TestAboutDialog) #include "testaboutdialog.moc" AntiMicroX-antimicrox-b300273/tests/testaddeditautoprofiledialog.cpp000066400000000000000000000077161471077622000257630ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #inlude "addeditautoprofiledialog.h" #include /* AutoProfileInfo* getAutoProfile() const; // if not empty then 1) profileLineEdit must be equal to getAutoProfile()->getProfileLocation() 2) devicesComboBox must be equal to getAutoProfile()->getDeviceName() 3) winClassLineEdit must be equal to getAutoProfile()->getWindowClass() 4) if getAutoProfile()->isPartialState() then should be setPartialCheckBox->checked() 5) if getAutoProfile()->isCurrentDefault() then should be asDefaultCheckBox->checked() 6) if getAutoProfile()->getWindowName() is not empty then should be winNameLineEdit->text() == getAutoProfile()->getWindowName() 7) if getAutoProfile()->getExe() is not empty then should be applicationLineEdit->text() == getAutoProfile()->getExe() //QString getOriginalGUID() const; QString getOriginalUniqueID() const; QString getOriginalExe() const; QString getOriginalWindowClass() const; QString getOriginalWindowName() const; QList *getDevices() const; // cannot be empty AntiMicroSettings *getSettings() const; // cannot be empty bool getEditForm() const; bool getDefaultInfo() const; // QList const& getReservedGUIDs(); QList const& getReservedUniques(); // cannot be empty profileBrowsePushButton not disabled detectWinPropsSelectWindowPushButton not disabled devicesComboBox not disabled and not empty asDefaultCheckBox not disabled if devicesComboBox first element is not -1 asDefaultCheckBox disabled if devicesComboBox first element is -1 buttonBox Cancel not disabled applicationPushButton not disabled selectWindowPushButton not disabled profileLineEdit not disabled winClassLineEdit not disabled winNameLineEdit not disabled applicationLineEdit not disabled buttonBox Ok disabled if profileLineEdit is empty and doesn't exist and devicesComboBox first element is empty and winClassLineEdit is empty buttonBox Ok enabled if profileLineEdit isn't empty and exist and devicesComboBox first element is not empty and winClassLineEdit is not empty test keyClick on profileBrowsePushButton test keyClick on detectWinPropsSelectWindowPushButton test keyClick on buttonBox->cancel test keyClick on applicationPushButton test keyClick on selectWindowPushButton test mouseClick on profileBrowsePushButton test mouseClick on detectWinPropsSelectWindowPushButton test mouseClick on buttonBox->cancel test mouseClick on applicationPushButton test mouseClick on selectWindowPushButton */ class TestAddEditAutoProfileDialog: public QObject { Q_OBJECT public: TestAddEditAutoProfileDialog(QObject* parent = 0); void checkAutoProfile(); void checkOriginalUniqueIDs(); private slots: private: AddEditAutoProfileDialog addEditAutoProfileDialog; }; TestAddEditAutoProfileDialog::TestAddEditAutoProfileDialog(QObject* parent) : QObject(parent), addEditAutoProfileDialog() { QTestEventLoop::instance().enterLoop(1); } // QTEST_MAIN(TestAddEditAutoProfileDialog) #include "testaddeditautoprofiledialog.moc" AntiMicroX-antimicrox-b300273/tests/testadvancebuttondialog.cpp000066400000000000000000000152301471077622000247360ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "advancebuttondialog.h" #include /* window title should be Advanced: gamepadBtn first slot cannot be empty first slot value should be equal to last pressed button if getAssignedSlots() is not empty then slots should be equal and in order to getAssignedSlots() elements if from comboBox is chosen "Blank or KB/M" then text should be tr("Insert a new blank slot.") if from comboBox is chosen "Cycle" then text should be tr("Slots past a Cycle action will be executed " "on the next button press. Multiple cycles can be added " "in order to create partitions in a sequence.") if from comboBox is chosen "Delay" then text should be tr("Delays the time that the next slot is activated " "by the time specified. Slots activated before the " "delay will remain active after the delay time " "has passed.") if from comboBox is chosen "Distance" then text should be tr("Distance action specifies that the slots afterwards " "will only be executed when an axis is moved " "a certain range past the designated dead zone.") if from comboBox is chosen "Execute" then text should be tr("Execute program when slot is activated.") if from comboBox is chosen "Hold" then text should be tr("Insert a hold action. Slots after the action will only be " "executed if the button is held past the interval specified.") if from comboBox is chosen "Load" then text should be tr("Chose a profile to load when this slot is activated.") if from comboBox is chosen "Mouse Mod" then text should be tr("Mouse mod action will modify all mouse speed settings " "by a specified percentage while the action is being processed. " "This can be useful for slowing down the mouse while " "sniping.") if from comboBox is chosen "Pause" then text should be tr("Insert a pause that occurs in between key presses.") if from comboBox is chosen "Press Time" then text should be tr("Specify the time that keys past this slot should be " "held down.") if from comboBox is chosen "Release" then text should be tr("Insert a release action. Slots after the action will only be " "executed after a button release if the button was held " "past the interval specified.") if from comboBox is chosen "Set Change" then text should be tr("Change to selected set once slot is activated.") if from comboBox is chosen "Text Entry" then text should be tr("Full string will be typed when a " "slot is activated.") if last empty slot clicked and press some keyboard value it should hold new value from keyboard if clicked "Clear all" button then there should be only one slot that is empty if clicked "Delete" button and if current slot is not first, then should be destroyed if clicked "Delete" burron on first slot, but there are other slots, then first slot is the second one, previous first slot is destroyed if clicked "Delete" button on first slot and there aren't any other slots, then the first slot is not destroyed but is empty Toggle->checkbox is not disabled if Turbo->checkbox is not checked then turboSlider is disabled if Turbo->checkbox is checked then turboSlider is enabled if Turbo->delay label is equal to sliderValue / 100.0 + sec. if Turbo->rate is equal to 100.0 / sliderValue + /sec. if Set Selector->comboBox->count == 22 enum SlotTypeComboIndex { KBMouseSlot = 0, CycleSlot, DelaySlot, DistanceSlot, ExecuteSlot, HoldSlot, LoadSlot, MouseModSlot, PauseSlot, PressTimeSlot, ReleaseSlot, SetChangeSlot, TextEntry }; if SlotTypeComboIndex::KBMouseSlot == 0, SlotTypeComboIndex::CycleSlot == 1 itd if last empty slot clicked and press some keyboard value it should hold new value from keyboard if clicked "Clear all" button then there should be only one slot that is empty if clicked "Delete" button and if current slot is not first, then should be destroyed if clicked "Delete" burron on first slot, but there are other slots, then first slot is the second one, previous first slot is destroyed if clicked "Delete" button on first slot and there aren't any other slots, then the first slot is not destroyed but is empty Toggle->checkbox is not disabled if Turbo->checkbox is not checked then turboSlider is disabled if Turbo->checkbox is checked then turboSlider is enabled if Turbo->delay label is equal to sliderValue / 100.0 + sec. if Turbo->rate is equal to 100.0 / sliderValue + /sec. if Set Selector->comboBox->count == 22 enum SlotTypeComboIndex { KBMouseSlot = 0, CycleSlot, DelaySlot, DistanceSlot, ExecuteSlot, HoldSlot, LoadSlot, MouseModSlot, PauseSlot, PressTimeSlot, ReleaseSlot, SetChangeSlot, TextEntry }; if SlotTypeComboIndex::KBMouseSlot == 0, SlotTypeComboIndex::CycleSlot == 1 itd if slot->getSlotMode() == JoyButtonSlot::JoySetChange then ui->slotSetChangeComboBox->findData(QVariant(slot->getSlotCode())) >= 0 close/cancel button cannot be disabled */ class TestAdvanceButtonDialog: public QObject { Q_OBJECT public: TestAdvanceButtonDialog(QObject* parent = 0); private slots: private: AdvanceButtonDialog advanceButtonDialog; }; TestAdvanceButtonDialog::TestAdvanceButtonDialog(QObject* parent) : QObject(parent), advanceButtonDialog() { QTestEventLoop::instance().enterLoop(1); } // QTEST_MAIN(TestAdvanceButtonDialog) #include "testadvancebuttondialog.moc" AntiMicroX-antimicrox-b300273/tests/testbuttoneditdialog.cpp000066400000000000000000000051411471077622000242620ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "buttoneditdialog.h" #include /* if slotSummaryLabel->text() == tr("[NO KEY]") and lastJoyButton is nullptr lastJoyButton->getSlotsString().replace("&", "&&") == tr("[NO KEY]") then advancedPushButton should be disabled if slotSummaryLabel->text() != tr("[NO KEY]") and lastJoyButton is not nullptr and lastJoyButton->getSlotsString().replace("&", "&&") != tr("[NO KEY]") then advancedPushButton should be enabled toggleCheckBox should be checked if lastJoyButton->getToggleState() turboCheckBox should be checked if lastJoyButton->isUsingTurbo() buttonNameLineEdit cannot be disabled actionNameLineEdit cannot be disabled buttonBox->Cancel cannot be disabled virtualKeyMouseTabWidget->tab(0)->->findChildren () check if each QString getXcodestring() const; != "" QString getDisplayString() const; != tr("[NO KEY]") int getKeycode() const; != 0 int getQkeyalias() const; != 0 only if it's not a none button and otherKeysPushbutton QList newlist = mouseTab->findChildren(); QListIterator iter(newlist); while (iter.hasNext()) { VirtualMousePushButton *mousebutton = iter.next(); // test if getMouseCode() is not null or less } getOtherKeysMenu()-actions() if AntKeyMapper::getInstance()->returnQtKey(oneFromListAction) != 0 */ class TestButtonEditDialog: public QObject { Q_OBJECT public: TestButtonEditDialog(QObject* parent = 0); private slots: private: ButtonEditDialog buttonEditDialog; }; TestButtonEditDialog::TestButtonEditDialog(QObject* parent) : QObject(parent), buttonEditDialog() { QTestEventLoop::instance().enterLoop(1); } // QTEST_MAIN(TestButtonEditDialog) #include "testbuttoneditdialog.moc" AntiMicroX-antimicrox-b300273/tests/testcalibration.cpp000066400000000000000000000100041471077622000232020ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "calibration.h" #include /* resetBtn should be enabled when !stick->wasCalibrated() resetBtn should be disabled when stick->wasCalibrated() Calibration->findChildren() count is equal to 2 startButton cannot be disabled cancelBtn cannot be disabled saveBtn is enabled when ui->steps->text() == tr("\n---Calibration done!---\n") && stick->setCalibrationSummary != ui->Information->text() || this->text != stick->setCalibrationSummary saveBtn is disabled when ui->steps->text() != tr("\n---Calibration done!---\n") && stick->setCalibrationSummary == ui->Information->text() || this->text == stick->setCalibrationSummary controllersBox->count() == this->joysticks->count int currContrBoxIndex = ui->controllersBox->currentIndex(); QList sticksList = joysticks->value(currContrBoxIndex)->getSetJoystick(currContrBoxIndex)->getSticks().values(); QList currStick(sticksList); ui->axesBox->count == currStick->count // test for other controllers and sticks too at the same time if each controlstick.data()->thread()->priority() != InheritPriority // if each thread is running, otherwise show priority if window title == tr("Calibration") if ui->stickStatusBoxWidget->getStick == ui->axesBox at 0 // ACTIONS if there are ui->axesBox->count > 1 choose the next one and check if ui->stickStatusBoxWidget->getStick == ui->axesBox at 0 && joyAxisX = controlstick->getAxisX(); joyAxisY = controlstick->getAxisY(); if progressBarsLayout->->itemAt(0)->widget() == tr("Axis %1").arg(joyAxisX->getRealJoyIndex()) and progressBarsLayout->->itemAt(2)->widget() == tr("Axis %1").arg(joyAxisY->getRealJoyIndex()) check results of connect(joyAxisX, &JoyAxis::moved, this, &Calibration::checkX); connect(joyAxisY, &JoyAxis::moved, this, &Calibration::checkY); test methods 1) no values 2) various expected values 3) various unexpected values 4) really big values 5) values below 0 int Calibration::chooseMinMax(QString min_max_sign, QList ax_values) Calibration::checkX(int value) Calibration::checkY(int value) Calibration::setController(QString controllerName) Calibration::setProgressBars(int inputDevNr, int setJoyNr, int stickNr) Calibration::setProgressBars(JoyControlStick* controlstick) bool Calibration::enoughProb(int x_count, int y_count, QString character) int Calibration::calibratedDeadZone(int center, int deadzone) void Calibration::summarizeValues(int &numbFromList, const int &mappednumb) void Calibration::getMinVal(int &numbFromList, const int &mappednumb) void Calibration::getMaxVal(int &numbFromList, const int &mappednumb) void Calibration::setQuadraticZoneCalibrated(int &max_axis_val_x, int &min_axis_val_x, int &max_axis_val_y, int &min_axis_val_y) void Calibration::restoreCalValues() -> if all local variables are default again */ class TestCalibration: public QObject { Q_OBJECT public: TestCalibration(QObject* parent = 0); private slots: private: TestCalibration calibrationDialog; }; TestCalibration::TestCalibration(QObject* parent) : QObject(parent), Calibration() { QTestEventLoop::instance().enterLoop(1); } // QTEST_MAIN(TestAdvanceButtonDialog) #include "testcalibration.moc" AntiMicroX-antimicrox-b300273/tests/testjoycontrolstickeditdialog.cpp000066400000000000000000000100321471077622000262020ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "joycontrolstickeditdialog.h" #include /* presetsComboBox->count should be 12 joyModeComboBox->count should be 4 deadZoneSlider->value == stick->getDeadZone() deadZoneSpinBox->value == stick->getDeadZone() maxZoneSlider->value == stick->getMaxZone() maxZoneSpinBox->value == stick->getMaxZone() diagonalRangeSlider->value == stick->getDiagonalRange() diagonalRangeSpinBox->value == stick->getDiagonalRange() squareStickSlider->value == stick->getCircleAdjust() * 100 squareStickSpinBox->value == stick->getCircleAdjust() * 100 stickDelaySlider->value == stick->getStickDelay() * .1 stickDelayDoubleSpinBox->value == stick->getStickDelay() * .001 modifierPushButton->text == stick->getModifierButton()->getSlotsSummary() stickNameLineEdit->text == stick->getStickName() QString xCoorString = QString::number(stick->getXCoordinate()); if (stick->getCircleAdjust() > 0.0) { xCoorString.append(QString(" (%1)").arg(stick->getCircleXCoordinate())); } xCoordinateLabel->text == xCoorString QString yCoorString = QString::number(stick->getYCoordinate()); if (stick->getCircleAdjust() > 0.0) { yCoorString.append(QString(" (%1)").arg(stick->getCircleYCoordinate())); } yCoordinateLabel->text() == yCoorString distanceLabel->text() == QString::number(stick->getAbsoluteRawDistance()) diagonalLabel->text() == QString::number(stick->calculateBearing()) fromSafeZoneValueLabel->text() == QString::number(stick->getDistanceFromDeadZone() * 100.0) stickStatusBoxWidget->getStick() == stick stickStatusBoxWidget has to be visible mouseSettingsPushButton runs new window mouseSettingsPushButton is never disabled presetsComboBox is not disabled joyModeComboBox is not disabled deadZoneSlider is not disabled maxZoneSlider is not disabled diagonalRangeSlider is not disabled squareStickSlider is not disabled stickDelaySlider is not disabled stickNameLineEdit is not disabled deadZoneSlider->setValue(int) deadZoneSlider->value() == deadZoneSpinBox->value() stickStatusBoxWidget->getStick()->getDeadZone() maxZoneSlider->setValue(int) maxZoneSlider->value() == maxZoneSlider->value() stickStatusBoxWidget->getStick()->getMaxZone() diagonalRangeSlider->setValue(int) diagonalRangeSlider->value() == diagonalRangeSlider->value() stickStatusBoxWidget->getStick()->getDiagonalRange() squareStickSlider->setValue(int) squareStickSlider->value() == squareStickSpinBox->value() stickStatusBoxWidget->getStick()->getCircleAdjust() == squareStickSpinBox->value() / 100 stickDelaySlider->setValue(int) stickDelaySlider->value() == stickDelayDoubleSpinBox->value() stickStatusBoxWidget->getStick()->getStickDelay() == stickDelayDoubleSpinBox->value() / .001 window->title() == Set + stick->getStickName() */ class TestJoyControlStickEditDialog: public QObject { Q_OBJECT public: TestJoyControlStickEditDialog(QObject* parent = 0); private slots: private: JoyControlStickEditDialog axisEditDialog; }; TestJoyControlStickEditDialog::TestJoyControlStickEditDialog(QObject* parent) : QObject(parent), JoyControlStickEditDialog() { QTestEventLoop::instance().enterLoop(1); } // QTEST_MAIN(TestJoyControlStickEditDialog) #include "testjoycontrolstickeditdialog.moc" AntiMicroX-antimicrox-b300273/tests/testqkeydisplaydialog.cpp000066400000000000000000000054511471077622000244440ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "qkeydisplaydialog.h" #include /* label->text() cannot be empty buttonBox->Close cannot be disabled nativeTitleLabel->text() == tr("Native Key Value:") qtKeyTitleLabel->text() == tr("Qt Key Value:") antiTitleLabel->text() == tr("AntiMicroX Key Value:") label->text() is all visible label->text() contains label->text() contains nativeKeyLabel->text() at the start is 0x00000000 or empty qtKeyLabel->text() at the start is 0x00000000 or empty antimicroKeyLabel->text() at the start is 0x00000000 or empty run keyReleaseEvent(QKeyEvent *event) for all keys, that are physically present: // qnamespace.h -> enum Key { contains all adresses of keys in Qt // keysymdef.h and XF86keysym.h contain adresses of keys in X11 // input-event-codes.h contains addresses of keys in uinput if int virtualkey = event->nativeVirtualKey() is != 0 if it's X11 if X11Extras::getInstance()->getGroup1KeySym(virtualkey) > 0 then check out if if it's uinput QtKeyMapperBase *nativeKeyMapper = AntKeyMapper::getInstance()->getNativeKeyMapper(); int tempalias = nativeKeyMapper->returnQtKey(virtualkey); if AntKeyMapper::getInstance()->returnVirtualKey(tempalias) > 0 then check out if ui->nativeKeyLabel->text() == QString("0x%1").arg(finalvirtual, 0, 16) ui->qtKeyLabel->text() == QString("0x%1").arg(event->key(), 0, 16) ui->antimicroKeyLabel->text() == QString("0x%1").arg(AntKeyMapper::getInstance()->returnQtKey(finalvirtual), 0, 16) */ class TestQKeyDisplayDialog: public QObject { Q_OBJECT public: TestQKeyDisplayDialog(QObject* parent = 0); private slots: private: QKeyDisplayDialog qkeydisplaydialog; }; TestQKeyDisplayDialog::TestQKeyDisplayDialog(QObject* parent) : QObject(parent), QKeyDisplayDialog() { QTestEventLoop::instance().enterLoop(1); } // QTEST_MAIN(TestQKeyDisplayDialog) #include "testqkeydisplaydialog.moc" AntiMicroX-antimicrox-b300273/tests/testquicksetdialog.cpp000066400000000000000000000100321471077622000237240ustar00rootroot00000000000000/* antimicrox Gamepad to KB+M event mapper * Copyright (C) 2015 Travis Nickles * Copyright (C) 2020 Jagoda Górska * Copyright (C) 2020 Paweł Kotiuk * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "quicksetdialog.h" #include /* buttonBox->Close cannot be disabled joystickDialogLabel->text() cannot be empty getJoystick() cannot be null pointer if joystickDialogLabel->text() == ui->joystickDialogLabel->text().arg(joystick->getSDLName()).arg(joystick->getName()) QListIterator sticksList = currentset->getSticks().values(); if sticksList.hasNext() then device has sticks (amount = currentset->getSticks().values().count()) QListIterator axesList = currentset->getAxes()->values();; if axesList.hasNext() then device has axes (amount = currentset->getAxes()->values().count()) QListIterator dpadsList = currentset->getHats().values(); if dpadsList.hasNext() then device has dpads (amount = currentset->getHats().values().count()) QListIterator vdpadsList = currentset->getVdpads().values(); if vdpadsList.hasNext() then device has vdpads (amount = currentset->getVdpads().values().count()) QListIterator btnsList = currentset->getButtons().values(); if btnsList.hasNext() then device has buttons (amount = currentset->getButtons().values().count()) emit pressed stick qobject_cast(getLastPressedButton()) != nullptr add thread to list emit pressed axis possibleAxisAction && qobject_cast(getLastPressedButton()) != nullptr add thread to list emit pressed dpad qobject_cast(getLastPressedButton()) != nullptr add thread to list emit pressed vdpad qobject_cast(getLastPressedButton()) != nullptr add thread to list emit pressed button qobject_cast(getLastPressedButton()) != nullptr add thread to list emit pressed any button getHelper() cannot be nullptr add thread to list all threads should be different run restoreJoystickState (below connections don't exist anymore): for each stickbutton connect(stickbutton, &JoyControlStickButton::clicked, this, [this, stickbutton]() { showStickButtonDialog(stickbutton); }); for each naxisbutton connect(naxisbutton, &JoyAxisButton::clicked, this, [this, naxisbutton]() { showAxisButtonDialog(naxisbutton); }); for each paxisbutton connect(paxisbutton, &JoyAxisButton::clicked, this, [this, paxisbutton]() { showAxisButtonDialog(paxisbutton); }); for each dpadbutton connect(dpadbutton, &JoyDPadButton::clicked, this, [this, dpadbutton] { showDPadButtonDialog(dpadbutton); }); for each vdpadbutton connect(dpadbutton, &JoyDPadButton::clicked, this, [this, dpadbutton] { showDPadButtonDialog(dpadbutton); }); for each button connect(button, &JoyButton::clicked, this, [this, button] { showButtonDialog(button); }); */ class TestQuickSetDialog: public QObject { Q_OBJECT public: TestQuickSetDialog(QObject* parent = 0); private slots: private: QuickSetDialog quicksetdialog; }; TestQuickSetDialog::TestQuickSetDialog(QObject* parent) : QObject(parent), QuickSetDialog() { QTestEventLoop::instance().enterLoop(1); } // QTEST_MAIN(TestQuickSetDialog) #include "testquicksetdialog.moc"